0

我正在尝试连接 4 个表,其中一个表没有所有匹配的 ID,但我仍然需要显示连接的结果,甚至是没有相应 ID 的行。

这是我正在谈论的一个例子:

示例表:

    DECLARE @Table1 TABLE(id INT 主键集群,ts DateTime,tbl2_id INT,价格 DECIMAL(4,2),tbl3_id INT,tbl4_id INT)

    插入@Table1 值(1, '2013-07-25 09:30:00', 10, 10.25, 1);
    插入@Table1 值(2, '2013-07-25 10:25:00', 20, 25.25, 1);
    插入@Table1 值(3, '2013-07-25 11:45:00', 30, 30.15, 2);
    插入@Table1 值(4, '2013-07-25 13:31:00', 40, 80.40, 2);

    DECLARE @Table2 TABLE (id INT PRIMARY KEY CLUSTERED,符号 VARCHAR(25),tbl1_id int)

    插入@Table2 值(10,'XYZ',1);
    插入@Table2 值(20,'ABC',2);
    插入@Table2 值(30,'RST',3);
    插入@Table2 值(40,'EFG',4);

    DECLARE @Table3 TABLE (id INT PRIMARY KEY CLUSTERED, exch VARCHAR(25))

    插入@Table3 值(1,'A');
    插入@Table3 值(2,'B');
    插入@Table3 值(3,'C');
    插入@Table3 值(4,'D');

    声明 @Table4 表(id​​ INT 主键集群,int tbl1_id,cnt INT)

    插入@Table4 值(1、2、19);
    插入@Table4 值(2、4、2013);

示例查询:

    选择 tbl1.id, tbl1.ts, tbl2.symbol, IFNULL(tbl3.cnt,0) AS cnt

    从表 1 tbl1

    加入表 2 tbl2
    ON tbl1.tbl2_id = tbl2.id

    加入表 3 tbl3
    ON tbl3.id = tbl1.tbl3_id

    左外连接表4 tbl4
    ON tbl1.tbl4_id = tbl4.id

    WHERE tbl1.ts 在 '2013-07-25 09:30:00 和 '2013-07-25 16:00:00' 之间
    AND tbl1.price >= 15.00
    限制 1000;

所以基本上我想要做的是如果 tbl4 没有 tbl1_id 我仍然希望看到 table1 的结果但显示 Cnt 的值为 0 ......当我运行这个查询时我得到了一堆重复条目和数据看起来不正确。

4

2 回答 2

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;
于 2013-07-25T22:06:10.803 回答
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与您的其余示例数据相加,因为您的插入语句中没有值 fortbl3_id或 for new introduction tbl4_id。而且tbl1_id专栏现在似乎是不必要的。

因此恕我直言,您需要重新访问和更正您的示例数据。发布所需的输出也可以帮助您获得答案。


现在,这是一个有效的查询,它基于您上次编辑之前的数据架构。除了部分之外,它将在 MySql 和 SQL Server 中成功运行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

输出:

| 身份证 | TS | 符号 | 碳纳米管 |
-------------------------------------------------- --
| 2 | 2013 年 7 月 25 日 10:25:00+0000 | 美国广播公司 | 19 |
| 3 | 2013 年 7 月 25 日 11:45:00+0000 | RST | 0 |
| 4 | 2013 年 7 月 25 日 13:31:00+0000 | EFG | 2013 |

这是SQLFiddle (MySql) 演示
这里是SQLFiddle (SQL Server) 演示

于 2013-07-26T01:04:07.550 回答