【问题标题】:Include NULL in SQL Join when using WHERE使用 WHERE 时在 SQL Join 中包含 NULL
【发布时间】:2017-03-15 15:01:16
【问题描述】:

我有以下两张表:

  • TempUser22:57,000 行:
+------+-----------+
| Id   | Followers |
+------+-----------+
|  874 |     55542 |
| 1081 |    330624 |
| 1378 |     17919 |
| 1621 |       920 |
| 1688 |    255463 |
| 2953 |       751 |
| 3382 |    204466 |
| 3840 |    273489 |
| 4145 |       376 |
| ...  |       ... |
+------+-----------+
  • temporal_users:总共 10,000,000 行,3200 行,其中 Date=2010-12-31:
+---------------------+---------+--------------------+
| Date                | User_Id | has_original_tweet |
+---------------------+---------+--------------------+
| 2008-02-22 12:00:00 |  676493 |                  2 |
| 2008-02-22 12:00:00 |  815263 |                  1 |
| 2008-02-22 12:00:00 | 6245822 |                  1 |
| 2008-02-22 12:00:00 | 8854092 |                  1 |
| 2008-02-23 12:00:00 |  676493 |                  2 |
| 2008-02-23 12:00:00 |  815263 |                  1 |
| 2008-02-23 12:00:00 | 6245822 |                  1 |
| 2008-02-23 12:00:00 | 8854092 |                  1 |
| 2008-02-24 12:00:00 |  676493 |                  2 |
|    .............    |   ...   |                 .. |
+---------------------+---------+--------------------+

我正在对这些表运行以下连接查询:

SELECT sum(has_original_tweet), b.Id
  FROM temporal_users AS a
  RIGHT JOIN TempUser22 AS b
  ON a.User_ID = b.Id
  GROUP BY b.Id;

按预期返回 57,00 行,第一个字段的答案为 NULL:

+-------------------------+------+
| sum(has_original_tweet) | Id   |
+-------------------------+------+
|                    NULL |  874 |
|                    NULL | 1081 |
|                     135 | 1378 |
|                     164 | 1621 |
|                     652 | 1688 |
|                     691 | 2953 |
|                    NULL | 3382 |
|                    NULL | 3840 |
|                    NULL | 4145 |
|                     ... | .... |
+-------------------------+------+

但是,当添加指定日期的 WHERE 行时,如下所示:

SELECT sum(has_original_tweet), b.Id
  FROM temporal_users AS a
  RIGHT JOIN TempUser22 AS b
  ON a.User_ID = b.Id
  WHERE a.Date BETWEEN '2010-12-31-00:00:00' AND '2010-12-31-23:59:59'
  GROUP BY b.Id;

我收到以下答案,只有 3200 行,第一个字段中没有任何 NULL。

+-------------------------+---------+
| sum(has_original_tweet) | Id      |
+-------------------------+---------+
|                       1 |  797194 |
|                       1 |  815263 |
|                       0 |  820678 |
|                       1 | 1427511 |
|                       0 | 4653731 |
|                       1 | 5933862 |
|                       2 | 7530552 |
|                       1 | 7674072 |
|                       1 | 8149632 |
|                      .. |   ....  |
+-------------------------+---------+

我的问题是:对于给定日期,当给定日期的 temporal_user 中不存在 has_original_tweet 时,如何为 TempUser22 中的每个用户获取大小为 57,000 行的答案? /p>

谢谢。

【问题讨论】:

  • 你确定你得到的空值的日期超出了你指定的范围吗?

标签: mysql sql database join


【解决方案1】:
SELECT b.Id, SUM(a.has_original_tweet) s
FROM TempUser22 b
LEFT JOIN temporal_users a ON b.Id = a.User_Id
  AND a.Date BETWEEN '2010-12-31-00:00:00' AND '2010-12-31-23:59:59'
GROUP BY b.Id;

Id  s
1   null
2   1
3   null
4   3
5   null
6   null

为了调试,我使用了:

CREATE TEMPORARY TABLE TempUser22(Id INT, Followers INT)
  SELECT 1 Id, 10 Followers UNION ALL
  SELECT 2, 20 UNION ALL
  SELECT 3, 30 UNION ALL
  SELECT 4, 40 UNION ALL
  SELECT 5, 50 UNION ALL
  SELECT 6, 60
;
CREATE TEMPORARY TABLE temporal_users(`Date` DATETIME, User_Id INT, has_original_tweet INT)
  SELECT '2008-02-22 12:00:00' `Date`, 1 User_Id, 1 has_original_tweet UNION ALL

  SELECT '2008-12-31 12:00:00', 2, 1 UNION ALL
  SELECT '2010-12-31 12:00:00', 2, 1 UNION ALL
  SELECT '2012-12-31 12:00:00', 2, 1 UNION ALL

  SELECT '2008-12-31 12:00:00', 4, 9 UNION ALL
  SELECT '2010-12-31 12:00:00', 4, 1 UNION ALL
  SELECT '2010-12-31 12:00:00', 4, 2 UNION ALL
  SELECT '2012-12-31 12:00:00', 4, 9
;

【讨论】:

  • 就是这样!我必须避免使用 WHERE,只需使用 AND 代替。谢谢。
【解决方案2】:

这是因为NULL 值将始终从where 子句中丢弃

您可以在 where 子句中使用合并。

WHERE coalesce(a.Date, 'some-date-in-the-range') BETWEEN '2010-12-31-00:00:00' AND '2010-12-31-23:59:59'

相反,您强制null 值被视为有效。

【讨论】:

  • 谢谢,但不幸的是它不起作用,这个语句没有返回所有的 57,000 个 b.Id
  • 用 AND 替换 WHERE 确实成功了,不过谢谢。
  • 当您使用外连接(无论是左连接还是右连接)并在第二个表上放置 where 条件时,您会强制连接成为内连接。因此,如果您在表 'b' 或 RIGHT JOIN 表 b 上放置条件,并且在表 'a' 上放置条件,则左连接 b 需要 ON 子句中的条件而不是 WHERE。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-27
  • 1970-01-01
  • 2016-10-27
  • 2016-11-30
  • 2020-08-10
相关资源
最近更新 更多