我正在尝试连接4个表,其中一个表没有所有匹配的ID但是我仍然需要显示连接的结果,甚至是没有相应ID的行。
这是我正在谈论的一个例子:
示例表:
DECLARE @Table1 TABLE (id INT PRIMARY KEY CLUSTERED, ts DateTime, tbl2_id INT, price DECIMAL(4,2), tbl3_id INT, tbl4_id INT) INSERT INTO @Table1 VALUES(1, '2013-07-25 09:30:00', 10, 10.25, 1); INSERT INTO @Table1 VALUES(2, '2013-07-25 10:25:00', 20, 25.25, 1); INSERT INTO @Table1 VALUES(3, '2013-07-25 11:45:00', 30, 30.15, 2); INSERT INTO @Table1 VALUES(4, '2013-07-25 13:31:00', 40, 80.40, 2); DECLARE @Table2 TABLE (id INT PRIMARY KEY CLUSTERED, symbol VARCHAR(25), tbl1_id int) INSERT INTO @Table2 VALUES(10, 'XYZ', 1); INSERT INTO @Table2 VALUES(20, 'ABC', 2); INSERT INTO @Table2 VALUES(30, 'RST', 3); INSERT INTO @Table2 VALUES(40, 'EFG', 4); DECLARE @Table3 TABLE (id INT PRIMARY KEY CLUSTERED, exch VARCHAR(25)) INSERT INTO @Table3 VALUES(1, 'A'); INSERT INTO @Table3 VALUES(2, 'B'); INSERT INTO @Table3 VALUES(3, 'C'); INSERT INTO @Table3 VALUES(4, 'D'); DECLARE @Table4 TABLE (id INT PRIMARY KEY CLUSTERED, int tbl1_id, cnt INT) INSERT INTO @Table4 VALUES(1, 2, 19); INSERT INTO @Table4 VALUES(2, 4, 2013);
示例查询:
SELECT tbl1.id, tbl1.ts, tbl2.symbol, IFNULL(tbl3.cnt,0) AS cnt FROM TABLE1 tbl1 JOIN TABLE2 tbl2 ON tbl1.tbl2_id = tbl2.id JOIN TABLE3 tbl3 ON tbl3.id = tbl1.tbl3_id LEFT OUTER JOIN TABLE4 tbl4 ON tbl1.tbl4_id = tbl4.id WHERE tbl1.ts BETWEEN '2013-07-25 09:30:00 AND '2013-07-25 16:00:00' AND tbl1.price >= 15.00 LIMIT 1000;
所以基本上我要做的是如果tbl4没有tbl1_id我仍然希望看到来自table1的结果但是为Cnt显示0值...当我运行这个查询时我是得到一堆重复的条目,数据看起来不正确。
答案 0 :(得分:1)
您只返回来自联接左侧的匹配项。将表4的连接更改为右连接,它将返回右侧的所有记录,无论如何。我知道这是一个不能与假数据一起使用的示例查询。但我必须与你给我的东西一起工作。这可能不会通过复制和粘贴工作,但理论是正确的,你只需要修改它。如果您提供更详细的信息,我会根据它进行定制。
SELECT tbl1.id, tbl1.ts, tbl2.symbol, IFNULL(tbl3.cnt,0) AS cnt
FROM TABLE1 tbl1
JOIN TABLE2 tbl2
ON tbl1.tbl2_id = tbl2.id
JOIN TABLE3 tbl3
ON tbl3.id = tbl1.tbl3_id
RIGHT JOIN TABLE4 tbl4
ON tbl1.tbl4_id = tbl4.id
WHERE tbl1.ts BETWEEN '2013-07-25 09:30:00 AND '2013-07-25 16:00:00'
AND tbl1.price >= 15.00
LIMIT 1000;
答案 1 :(得分:0)
首先在您的示例代码中,您混合使用了SQL Server和MySql语法:
DECLARE TABLE
,CLUSTERED
是SQL Server功能IFNULL()
,LIMIT
是MySql的 其次 cnt
列在表4中而非表3中,因此IFNULL(tbl3.cnt,0)
不会飞。
第三次当您将tbl1.id = tbl4.tbl1_id
更改为tbl1.tbl4_id = tbl4.id
时,您的上一次修改不会与其他示例数据相加,因为您的插入中没有值tbl3_id
或新引入的tbl4_id
语句。现在似乎没有tbl1_id
列。
因此恕我直言,您需要重新访问并更正您的样本数据。发布所需的输出也可以帮助您获得答案。
现在,这是一个可以在上次编辑之前根据您的数据模式运行的查询。 除了LIMIT
部分
SELECT t1.id, t1.ts, t2.symbol, COALESCE(t4.cnt, 0) cnt
FROM Table1 t1 JOIN Table2 t2
ON t1.id = t2.tbl1_id JOIN Table3 t3
ON t1.tbl3_id = t3.id LEFT JOIN Table4 t4
ON t1.id = t4.tbl1_id
WHERE t1.ts BETWEEN '2013-07-25 09:30:00' AND '2013-07-25 16:00:00'
AND t1.price >= 15.00
LIMIT 1000 -- LIMIT will work only in MySql
输出:
| ID | TS | SYMBOL | CNT | ---------------------------------------------------- | 2 | July, 25 2013 10:25:00+0000 | ABC | 19 | | 3 | July, 25 2013 11:45:00+0000 | RST | 0 | | 4 | July, 25 2013 13:31:00+0000 | EFG | 2013 |