将一张表与另一张表基于第二张表中的行满足的某些条件连接起来。

huangapple go评论59阅读模式
英文:

Join one table to another based on certain conditions met by rows in second table

问题

对于Table 1中的每一行,您想创建一个SQL查询,以便在Table 2中查找大于Table 1中的ms值的前两行。结果输出将是Table 1,其中添加了六列,显示与Table 1中ms值相对应的Table 2中前两行的ms、bid和ask。

鉴于行数较多,进行交叉连接然后筛选可能太多(因为这必须在多次对多个数据执行,而不仅仅一次)。您正在寻找一个高效的解决方案。您是SQL新手,尝试了交叉连接。请帮忙!

英文:

I have two tables. I want to create a SQL query such that for each row in Table 1, I want find the first two rows in Table 2 such ms.Table2 > ms.Table1. The resulting output will be Table 1 with six additional columns added showing ms, bid, ask from Table 2 corresponding to first two rows from Table 2 where ms is just greater than ms in Table 1.

Given the large number of rows, doing a cross-join and then filtering may be too much (since this has to be done many times over multiple data, not just once). Looking for an efficient solution. I am new to SQL so feel this is bit much for me, though I did try a cross-join. Please help!

Table 1 (2000+ rows)

ms price bid ask
34200106 1.48 1.46 1.5
34200106 1.48 1.46 1.5
34202812 1.56 1.53 1.56
34202815 1.56 1.53 1.56
34202823 1.56 1.53 1.56
34204227 1.56 1.53 1.57
34207137 1.56 1.55 1.57
34208496 1.57 1.56 1.57
34208938 1.57 1.55 1.57
34208938 1.57 1.55 1.57
34208943 1.57 1.55 1.57
34208951 1.57 1.56 1.57

Table 2 (300000+ rows)

ms bid ask
34200009 1.46 1.51
34200011 1.46 1.5
34200106 1.46 1.5
34200171 1.46 1.5
34200195 1.46 1.5
34200195 1.46 1.51
34200201 1.46 1.52
34200202 1.46 1.52
34200276 1.46 1.52
34200296 1.46 1.52
34200305 1.46 1.52
34200306 1.46 1.52
34200308 1.46 1.53
34200326 1.46 1.53

答案1

得分: 1

创建表格table1
    ("ms" 整数, "price" 整数, "bid" 整数, "ask" 整数)
;

插入到table1
    ("ms", "price", "bid", "ask") 
    (34200106, 1.48, 1.46, 1.5),
    (34200106, 1.48, 1.46, 1.5),
    (34202812, 1.56, 1.53, 1.56),
    (34202815, 1.56, 1.53, 1.56),
    (34202823, 1.56, 1.53, 1.56),
    (34204227, 1.56, 1.53, 1.57),
    (34207137, 1.56, 1.55, 1.57),
    (34208496, 1.57, 1.56, 1.57),
    (34208938, 1.57, 1.55, 1.57),
    (34208938, 1.57, 1.55, 1.57),
    (34208943, 1.57, 1.55, 1.57),
    (34208951, 1.57, 1.56, 1.57)
;

插入到table2
    ("ms", "bid", "ask") 
    (34200009, 1.46, 1.51),
    (34200011, 1.46, 1.5),
    (34200106, 1.46, 1.5),
    (34200171, 1.46, 1.5),
    (34200195, 1.46, 1.5),
    (34200195, 1.46, 1.51),
    (34200201, 1.46, 1.52),
    (34200202, 1.46, 1.52),
    (34200276, 1.46, 1.52),
    (34200296, 1.46, 1.52),
    (34200305, 1.46, 1.52),
    (34200306, 1.46, 1.52),
    (34200308, 1.46, 1.53),
    (34200326, 1.46, 1.53)
;

创建或替换函数foo()
返回表格("ms" 整数, "price" 整数, "bid" 整数, "ask" 整数)
语言plpgsql 如下:
DECLARE 
  x 整数 ;
  table1_cursor 游标 FOR 选择 t1."ms"  table1 t1; 
开始
  如果不存在则创建临时表temp_table
    选择 *
     table1
     temp_table;

  对于 x  table1_cursor 循环:
    temp_table插入 ("ms", "price", "bid", "ask")
    选择 t2."ms", , t2."bid", t2."ask"  table2 t2
    其中 t2."ms" > x."ms"
     t2."ms" 升序排列 
    限制 2;
  结束循环;

返回查询结果 
选择 t3."ms", t3."price", t3."bid", t3."ask"
 temp_table t3;
如果存在则删除表格temp_table;

结束
$$;

选择 *  foo();
英文:

you could use a loop, but it will still be somewhat slow, but much faster than a cross join

CREATE TABLE table1
("ms" int, "price" int, "bid" int, "ask" int)
;
INSERT INTO table1
("ms", "price", "bid", "ask")
VALUES
(34200106, 1.48, 1.46, 1.5),
(34200106, 1.48, 1.46, 1.5),
(34202812, 1.56, 1.53, 1.56),
(34202815, 1.56, 1.53, 1.56),
(34202823, 1.56, 1.53, 1.56),
(34204227, 1.56, 1.53, 1.57),
(34207137, 1.56, 1.55, 1.57),
(34208496, 1.57, 1.56, 1.57),
(34208938, 1.57, 1.55, 1.57),
(34208938, 1.57, 1.55, 1.57),
(34208943, 1.57, 1.55, 1.57),
(34208951, 1.57, 1.56, 1.57)
;

> status
> CREATE TABLE
>

> status
> INSERT 0 12
>

CREATE TABLE table2
("ms" int, "bid" int, "ask" int)
;
INSERT INTO table2
("ms", "bid", "ask")
VALUES
(34200009, 1.46, 1.51),
(34200011, 1.46, 1.5),
(34200106, 1.46, 1.5),
(34200171, 1.46, 1.5),
(34200195, 1.46, 1.5),
(34200195, 1.46, 1.51),
(34200201, 1.46, 1.52),
(34200202, 1.46, 1.52),
(34200276, 1.46, 1.52),
(34200296, 1.46, 1.52),
(34200305, 1.46, 1.52),
(34200306, 1.46, 1.52),
(34200308, 1.46, 1.53),
(34200326, 1.46, 1.53)
;

> status
> CREATE TABLE
>

> status
> INSERT 0 14
>

CREATE OR REPLACE FUNCTION foo() 
RETURNS TABLE ("ms" int, "price" int, "bid" int, "ask" int)
language plpgsql as $$
DECLARE 
x int ;
table1_cursor CURSOR FOR SELECT t1."ms" FROM table1 t1; 
BEGIN
CREATE TEMP TABLE IF NOT EXISTS temp_table AS
SELECT *
FROM table1;
FOR x IN table1_cursor loop
INSERT INTO temp_table ("ms", "price", "bid", "ask")
SELECT t2."ms", NULL, t2."bid", t2."ask" FROM table2 t2
WHERE t2."ms" > x."ms"
ORDER BY t2."ms" 
LIMIT 2;
END loop;
RETURN QUERY 
SELECT t3."ms", t3."price", t3."bid", t3."ask"
from temp_table t3;
DROP TABLE temp_table;
END $$;
SELECT * FROM foo();

> status
> CREATE FUNCTION
>

ms price bid ask
34200106 1 1 2
34200106 1 1 2
34202812 2 2 2
34202815 2 2 2
34202823 2 2 2
34204227 2 2 2
34207137 2 2 2
34208496 2 2 2
34208938 2 2 2
34208938 2 2 2
34208943 2 2 2
34208951 2 2 2
34200171 null 1 2
34200195 null 1 2
34200171 null 1 2
34200195 null 1 2
> ``` status
> SELECT 16
> ```

fiddle

答案2

得分: 1

以下查询生成所描述的结果,而不对 table1 和 table2 进行完全的交叉连接:

SELECT table1.ms,
       table1.bid,
       table1.ask,
       t2.ms[1] AS ms1,
       t2.bids[1] AS bid1,
       t2.asks[1] AS ask1,
       t2.ms[2] AS ms2,
       t2.bids[2] AS bid2,
       t2.asks[2] AS ask2
  FROM table1
  CROSS JOIN LATERAL (SELECT ARRAY_AGG(t.ms) AS ms,
                             ARRAY_AGG(t.bid) AS bids,
                             ARRAY_AGG(t.ask) AS asks
                        FROM (SELECT table2.*
                                FROM table2
                               WHERE table2.ms > table1.ms
                               ORDER BY table2.ms
                               LIMIT 2
                             ) t
                     ) AS t2;
英文:

The following query produces the described results without doing a full cross join between table1 and table2:

SELECT table1.ms,
table1.bid,
table1.ask,
t2.ms[1] AS ms1,
t2.bids[1] AS bid1,
t2.asks[1] AS ask1,
t2.ms[2] AS ms2,
t2.bids[2] AS bid2,
t2.asks[2] AS ask2
FROM table1
CROSS JOIN LATERAL (SELECT ARRAY_AGG(t.ms) AS ms,
ARRAY_AGG(t.bid) AS bids,
ARRAY_AGG(t.ask) AS asks
FROM (SELECT table2.*
FROM table2
WHERE table2.ms > table1.ms
ORDER BY table2.ms
LIMIT 2
) t
) AS t2;

huangapple
  • 本文由 发表于 2023年5月8日 00:33:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/76195087.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定