SQL Left在过滤后加入丢失的行

时间:2013-09-11 20:19:45

标签: sql left-join

我有一个多表连接(示例中只显示了两个),我需要保留基表中的所有行。显然,我使用LEFT JOIN来包含基表上的所有行。如果没有WHERE子句,它可以很好地工作 - 当Right表中不存在行时,Left表中的行仍然显示,而右表中的列只有0。数据集中的前两行是左表中的标签和右表中的行数,按标签分组。当标签没有分配Table2的值时,我想要的只是0。

表1

Label | FK
----------
Blue  | 1
Red   | 2
Green | 3

表2

Values | Color | Date
---------------------------
Dog    | 1     | 02/02/2010
Cat    | 2     | 02/02/2010
Dog    | 1     | 02/02/2010
Cat    | 2     | 02/02/2010

查询

SELECT 1.Label, COUNT(2.values)
FROM Table1 1
    LEFT JOIN Table2 2 ON 1.fk = 1.pk
GROUP BY 1.Label

结果良好 - 无过滤器

Blue  | 2
Red   | 2
Green | 0

大!

我的问题是,当我添加过滤条件以从Right表中删除行时,我的左连接行将其删除(将它们清零),删除左行。即使他们的计数被过滤到零,我也需要保留左行。

SELECT 1.Label, COUNT(2.values)
FROM Table1 1
    LEFT JOIN Table2 2 ON 1.fk = 1.pk
WHERE 2.Date BETWEEN '1/1/2010' AND '12/31/2010'    
GROUP BY 1.Label

Bummer Result Set - After Filters

Blue | 2
Red  | 2

杜克斯!

那么,到底是什么?我是否需要获取带有过滤数据集的临时表,然后将其连接到左表?我错过了什么? 谢谢!

进行第二次加入或递归加入。得到我的“好”联接表,得到第二个“过滤”表,然后左键加入

4 个答案:

答案 0 :(得分:14)

您正在过滤where中的第二个表格。值可能为NULLNULL无法进行比较。

where条件移至on子句:

SELECT 1.Label, COUNT(2.values)
FROM Table1 1
    LEFT JOIN Table2 2 ON 1.fk = 1.pk and
              2.Date BETWEEN 1/1/2010 AND 12/31/2010    
GROUP BY 1.Label

答案 1 :(得分:3)

只需将WHERE子句中的条件移动到ON子句。

LEFT JOIN Table2 2 ON 1.fk = 1.pk AND 2.Date BETWEEN '1/1/2010' AND '12/31/2010'

答案 2 :(得分:0)

首先,我不认为将数字作为别名是个好主意。改为使用字符或单词。

我会把标准放在加入中。

SELECT T1.Label, COUNT(T2.values)
FROM Table1 T1
    LEFT JOIN Table2 T2 ON T1.fk = T1.pk
    AND T2.Date BETWEEN '20100101' AND '20101231'    
GROUP BY T1.Label

其他评论:

  1. 我会使用ANSI(yyyyMMdd)格式作为日期,因此不会有任何误解。
  2. 我会注意到BETWEEN,因为如果日期是'20101231 01:00',你想知道你想做什么并不清楚你想要包括那个日期吗? > =和< =或> =和<更清楚。

答案 3 :(得分:0)

如果您使用的是SQL Server,请在日期周围加上单引号。如果没有,那么它将评估表达式而不是日期。

BETWEEN '1/1/2010' AND '12/31/2010'