MySQL JOIN 独立于 WHERE 子句
MySQL JOIN independent of WHERE clause
我有两个表:
debates
----------------------
id | name
----------------------
1 | why is that?
2 | why is the other?
opinions
---------------------
id | debate | opinion
---------------------
1 | 1 | because
2 | 1 | NULL
如果我使用 left join ON opinions.debate = debates.id 我可以得到两个辩论 (1 , 2).
如果我在 left join WHERE (opinions.opinion ! = '' AND opinions.opinion IS NOT NULL) 我只得到 id = 1
的辩论
如何获得两条记录但仍然保持条件,因为我用它来统计记录?
例如。查询:
SELECT
debates.id,
COUNT(opinions.id) AS total_opinions
FROM debates
LEFT JOIN
`opinions` ON `opinions`.`debate` = `debates`.`id`
WHERE
`opinions`.`opinion` IS NOT NULL AND `opinions`.`opinion` != ''
GROUP BY
`debates`.`id`
应该return:
debates
-------------------
id | total_opinions
-------------------
1 | 1
2 | 0
将WHERE
子句的谓词移动到ON
:
SELECT debates.id,
COUNT(opinions.id) AS total_opinions
FROM debates
LEFT JOIN `opinions`
ON `opinions`.`debate` = `debates`.`id` AND
`opinions`.`opinion` IS NOT NULL AND
`opinions`.`opinion` != ''
GROUP BY `debates`.`id`
此查询将获取 debates
的 所有 条记录,并加入满足 [=12= 指定条件的 opinions
的记录] 谓词。如果没有匹配 NULL
返回,COUNT
聚合函数将忽略它。
LEFT OUTER JOIN 的目的是允许列出一个 table 的所有行,即使这些行未在另一个 table 中引用,如果这些条件存在,您将获得 NULL 值来自另一个 table。因此,即使其中一些没有意见,要获得所有辩论,您可以这样做:
FROM debates
LEFT OUTER JOIN `opinions` ON `opinions`.`debate` = `debates`.`id`
当辩论中没有意见时,意见中数据的所有列位置 table 都将为 NULL
如果您正在计算意见的数量,那么请务必注意,如果值为 NON NULL,COUNT() 函数只会递增 1。因此,以下将自动计算正确的意见数量,而无需过滤掉 NULL。
SELECT
debates.id
, COUNT(opinions.id) AS total_opinions
FROM debates
LEFT OUTER JOIN `opinions` ON `opinions`.`debate` = `debates`.`id`
GROUP BY
debates.id
现在,如果您确实在意见 table 中有行,其中意见是一个空白字符串,您可以这样做:
SELECT
debates.id
, COUNT(opinions.id) AS total_opinions
FROM debates
LEFT OUTER JOIN `opinions` ON `opinions`.`debate` = `debates`.`id`
AND `opinions`.`opinion` <> ''
GROUP BY
debates.id
或:
SELECT
debates.id
, COUNT(case when `opinions`.`opinion` <> '' then opinions.id end) AS total_opinions
FROM debates
LEFT OUTER JOIN `opinions` ON `opinions`.`debate` = `debates`.`id`
GROUP BY
debates.id
我有两个表:
debates
----------------------
id | name
----------------------
1 | why is that?
2 | why is the other?
opinions
---------------------
id | debate | opinion
---------------------
1 | 1 | because
2 | 1 | NULL
如果我使用 left join ON opinions.debate = debates.id 我可以得到两个辩论 (1 , 2).
如果我在 left join WHERE (opinions.opinion ! = '' AND opinions.opinion IS NOT NULL) 我只得到 id = 1
的辩论如何获得两条记录但仍然保持条件,因为我用它来统计记录?
例如。查询:
SELECT
debates.id,
COUNT(opinions.id) AS total_opinions
FROM debates
LEFT JOIN
`opinions` ON `opinions`.`debate` = `debates`.`id`
WHERE
`opinions`.`opinion` IS NOT NULL AND `opinions`.`opinion` != ''
GROUP BY
`debates`.`id`
应该return:
debates
-------------------
id | total_opinions
-------------------
1 | 1
2 | 0
将WHERE
子句的谓词移动到ON
:
SELECT debates.id,
COUNT(opinions.id) AS total_opinions
FROM debates
LEFT JOIN `opinions`
ON `opinions`.`debate` = `debates`.`id` AND
`opinions`.`opinion` IS NOT NULL AND
`opinions`.`opinion` != ''
GROUP BY `debates`.`id`
此查询将获取 debates
的 所有 条记录,并加入满足 [=12= 指定条件的 opinions
的记录] 谓词。如果没有匹配 NULL
返回,COUNT
聚合函数将忽略它。
LEFT OUTER JOIN 的目的是允许列出一个 table 的所有行,即使这些行未在另一个 table 中引用,如果这些条件存在,您将获得 NULL 值来自另一个 table。因此,即使其中一些没有意见,要获得所有辩论,您可以这样做:
FROM debates
LEFT OUTER JOIN `opinions` ON `opinions`.`debate` = `debates`.`id`
当辩论中没有意见时,意见中数据的所有列位置 table 都将为 NULL
如果您正在计算意见的数量,那么请务必注意,如果值为 NON NULL,COUNT() 函数只会递增 1。因此,以下将自动计算正确的意见数量,而无需过滤掉 NULL。
SELECT
debates.id
, COUNT(opinions.id) AS total_opinions
FROM debates
LEFT OUTER JOIN `opinions` ON `opinions`.`debate` = `debates`.`id`
GROUP BY
debates.id
现在,如果您确实在意见 table 中有行,其中意见是一个空白字符串,您可以这样做:
SELECT
debates.id
, COUNT(opinions.id) AS total_opinions
FROM debates
LEFT OUTER JOIN `opinions` ON `opinions`.`debate` = `debates`.`id`
AND `opinions`.`opinion` <> ''
GROUP BY
debates.id
或:
SELECT
debates.id
, COUNT(case when `opinions`.`opinion` <> '' then opinions.id end) AS total_opinions
FROM debates
LEFT OUTER JOIN `opinions` ON `opinions`.`debate` = `debates`.`id`
GROUP BY
debates.id