sql左联接在筛选后丢失行

5f0d552i  于 2021-06-23  发布在  Mysql
关注(0)|答案(4)|浏览(277)

我有一个多表联接(示例中只显示了两个),需要保留基表中的所有行。显然,我使用左联接来包含基表上的所有行。如果没有where子句,它的效果会很好——当右表中不存在行时,左表中的行仍会显示,右表中的列中只有一个0。数据集中的前两行是左表中的标签和右表中按标签分组的行数。当标签没有分配表2中的值时,我只需要计数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

太好了!
我的问题是,当我添加筛选条件以从右表中删除行时,左连接行的行将被删除(将其清零),左连接行将被删除。我需要保留左边的行,即使它们的计数被过滤到零。

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结果集-后过滤器

Blue | 2
Red  | 2

公爵!
怎么回事?我是否需要获得一个带有过滤数据集的临时表,然后将其连接到左表?我错过了什么?谢谢!
执行第二个联接或递归联接。得到我的“好”联接表,得到第二个“过滤”表,然后左联接它们

mo49yndu

mo49yndu1#

首先,我不认为用数字作为别名是个好主意。用一个字符或一个单词代替。
我会把标准放在连接中。

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

其他意见:
我会使用ansi(yyyymmdd)格式的日期,所以没有误解。
如果日期是'20101231 01:00',我会知道两者之间的时间间隔,因为不清楚您要做什么,您是否希望包括该日期?>=和<=或>=和<更清晰。

ltqd579y

ltqd579y2#

只需将条件移入 WHERE 条款 ON 条款。

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

qyyhg6bp3#

您正在筛选中的第二个表 where . 这些值可能是 NULL 以及 NULL 比较失败。
移动 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
gdrx4gfi

gdrx4gfi4#

如果您使用的是sql server,请在日期周围加上单引号。如果不是,那么它将计算表达式而不是日期。

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

相关问题