【问题标题】:MySQL Left Join Query not workingMySQL左连接查询不起作用
【发布时间】:2016-10-12 01:25:35
【问题描述】:

history table 包含我试图与participation table 匹配的日期。如果participation table 中不存在日期,那么我希望将记录拉出,以便输入参与数据。但是我所拥有的不起作用。这是我正在使用的内容的简要说明:

MariaDB [sotp]> describe history;
+--------------+------------------+------+-----+---------+----------------+
| Field        | Type             | Null | Key | Default | Extra          |
+--------------+------------------+------+-----+---------+----------------+
| historyid    | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| amount       | float            | NO   |     | NULL    |                |
| subsidy      | char(1)          | NO   |     | NULL    |                |
| last_payment | date             | NO   |     | NULL    |                |
| amount_paid  | float            | NO   |     | NULL    |                |
| balance      | float            | NO   |     | NULL    |                |
| attend       | char(1)          | NO   |     | N       |                |
| atend_date   | date             | NO   |     | NULL    |                |
| groupid      | int(11) unsigned | NO   |     | NULL    |                |
| clientid     | int(10) unsigned | NO   | MUL | NULL    |                |
| memberid     | int(10) unsigned | NO   | MUL | NULL    |                |
+--------------+------------------+------+-----+---------+----------------+

MariaDB [sotp]> select clientid, attend_date
-> from history
-> where memberid = "1"
-> AND MONTH(attend_date) = "10"
-> AND YEAR(attend_date) = "2016"
-> AND attend_date <> "0000-00-00"
-> ORDER BY attend_date ASC;
+----------+-------------+
| clientid | attend_date |
+----------+-------------+
|        3 | 2016-10-11  |
|        1 | 2016-10-11  |
|        7 | 2016-10-11  |
|        2 | 2016-10-11  |
|        4 | 2016-10-11  |
|        5 | 2016-10-11  |
|        8 | 2016-10-11  |
|        9 | 2016-10-11  |
+----------+-------------+

MariaDB [sotp]> describe participation;
+-----------+------------------+------+-----+---------+----------------+
| Field     | Type             | Null | Key | Default | Extra          |
+-----------+------------------+------+-----+---------+----------------+
| partid    | int(11)          | NO   | PRI | NULL    | auto_increment |
| notes     | varchar(255)     | NO   |     | NULL    |                |
| groupdate | date             | NO   |     | NULL    |                |
| clientid  | int(10) unsigned | NO   | MUL | NULL    |                |
| memberid  | int(10) unsigned | NO   | MUL | NULL    |                |
+-----------+------------------+------+-----+---------+----------------+

MariaDB [sotp]> select clientid, groupdate
-> from participation
-> where memberid = "1"
-> AND MONTH(groupdate) = "10"
-> AND YEAR(groupdate) = "2016"
-> AND groupdate <> "0000-00-00"
-> ORDER BY groupdate ASC;
+----------+------------+
| clientid | groupdate  |
+----------+------------+
|        2 | 2016-10-11 |
|        4 | 2016-10-11 |
+----------+------------+

还有我的left join 查询:

SELECT historyid, p.groupdate, h.attend_date, h.clientid, h.memberid
FROM history AS h
LEFT JOIN  participation AS p  ON p.groupdate = h.attend_date
WHERE h.memberid = "1"
AND MONTH(h.attend_date) = "10"
AND YEAR(h.attend_date) = "2016"
AND h.attend_date <> "0000-00-00"
ORDER BY h.attend_date ASC;
+-----------+------------+-------------+----------+----------+
| historyid | groupdate  | attend_date | clientid | memberid |
+-----------+------------+-------------+----------+----------+
|        58 | 2016-10-11 | 2016-10-11  |        3 |        1 |
|        61 | 2016-10-11 | 2016-10-11  |        2 |        1 |
|        59 | 2016-10-11 | 2016-10-11  |        1 |        1 |
|        62 | 2016-10-11 | 2016-10-11  |        4 |        1 |
|        60 | 2016-10-11 | 2016-10-11  |        7 |        1 |
|        63 | 2016-10-11 | 2016-10-11  |        5 |        1 |
|        61 | 2016-10-11 | 2016-10-11  |        2 |        1 |
|        64 | 2016-10-11 | 2016-10-11  |        8 |        1 |
|        62 | 2016-10-11 | 2016-10-11  |        4 |        1 |
|        65 | 2016-10-11 | 2016-10-11  |        9 |        1 |
|        63 | 2016-10-11 | 2016-10-11  |        5 |        1 |
|        64 | 2016-10-11 | 2016-10-11  |        8 |        1 |
|        65 | 2016-10-11 | 2016-10-11  |        9 |        1 |
|        58 | 2016-10-11 | 2016-10-11  |        3 |        1 |
|        59 | 2016-10-11 | 2016-10-11  |        1 |        1 |
|        60 | 2016-10-11 | 2016-10-11  |        7 |        1 |
+-----------+------------+-------------+----------+----------+

groupdate 字段应为 NULLmemberid 2 和 4 除外。另外,它提供了两次数据。我做错了什么?

最好的问候。

更新

kasparg的要求:

MariaDB [sotp]> select *
-> from participation;
+--------+-----------------------------------------------+------------+----------+----------+
| partid | notes                                         | groupdate  | clientid | memberid |
+--------+-----------------------------------------------+------------+----------+----------+
|    824 | aaaaaaaaaaaaaaaaaaaaaazzzzzzzzzzzzzzzzzzzzzzz | 2016-01-26 |        3 |        1 |
|    825 | lol hahaha and stuff                          | 2016-01-26 |        4 |        1 |
|    826 | aaaaaaaaaaaaaaaaaaaaaa                        | 2016-01-26 |        2 |        1 |
|    827 | zzzzzzzzzzzzzzaaaaaaaaaaaaaaaaaa              | 2016-01-26 |        1 |        1 |
|    828 | llllllllllllllllllllllllllllllllllll          | 2016-01-28 |        3 |        1 |
|    829 | bbbbbbbbbbbbbbbbbbb                           | 2016-01-28 |        1 |        1 |
|    830 | Absent                                        | 2016-01-28 |        4 |        1 |
|    831 | Absent                                        | 2016-01-28 |        2 |        1 |
|    832 | llllkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk           | 2016-01-29 |        5 |        1 |
|    833 | xxxxxxxxxxxxxxxzzzzzzzzzzzzzzzzzz             | 2016-01-29 |        4 |        1 |
|    834 | xxxxxxxxxxxxxxxxxxxxxxxx                      | 2016-01-29 |        2 |        1 |
|    835 | ccccccccccccccccccccccc                       | 2016-01-29 |        1 |        1 |
|    836 | llllkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk           | 2016-01-29 |        3 |        1 |
|   1063 | zzzzzzzzzzzzzzzzzzzzzzzzzzzz                  | 2016-01-30 |        3 |        1 |
|   1064 | ddddddddddddddddddddddddd                     | 2016-01-30 |        1 |        1 |
|   1065 | No entry made.                                | 2016-01-30 |        4 |        1 |
|   1066 | No entry made.                                | 2016-01-30 |        2 |        1 |
|   1075 | 2016-02-26: car wreck                         | 2016-10-11 |        2 |        1 |
|   1076 | 2016-02-26: broken legs                       | 2016-10-11 |        4 |        1 |
+--------+-----------------------------------------------+------------+----------+----------+

更新

MariaDB [sotp]> SELECT historyid, p.groupdate,  h.attend_date, p.clientid, h.clientid, h.memberid
-> FROM history AS h
-> LEFT JOIN  participation AS p  ON p.groupdate = h.attend_date and p.clientid = h.clientid
-> WHERE h.memberid = "1"
-> AND h.clientid = "1"
-> AND MONTH(h.attend_date) = "10"
-> AND YEAR(h.attend_date) = "2016"
-> AND h.attend_date <> "0000-00-00"
-> AND p.groupdate = "NULL"
-> ORDER BY h.attend_date ASC;
Empty set, 1 warning (0.00 sec)

我对@9​​87654334@ 进行了硬编码,但仍然一无所获。并且该记录应该为groupdate 返回一个NULL 值。

【问题讨论】:

  • 你能展示一下参与表里面的内容吗? SELECT * FROM 参与限制 10;
  • 我在使用 mariadb 时遇到了同样的问题。我发现做两个子查询是按照我想要的方式获取数据的唯一方法,afaik 这对于 mysql 来说是不必要的。 *.com/a/58173579/4227722

标签: mysql mariadb


【解决方案1】:

如果我理解正确,您希望获取缺少参与日期的记录。向 WHERE 子句添加附加条件:AND p.groupdate IS NULL

另外,请注意您仅在 groupdate 上加入,同时在 clientid 上加入,如下所示:LEFT JOIN participation AS p ON p.groupdate = h.attend_date and p.clientid = h.clientid

【讨论】:

  • 您对我的查询的评估是正确的。请看我的更新。你给我看的看起来是对的。所有的查询看起来都是对的……对我来说。但每次都失败。
  • 对不起。我对php 页面的更改进行了更改,但它仍然没有拉出NULL 记录。至少可以说,这令人费解。
  • 在您发布的数据中,您过滤 p.memberid =1,但不在您的查询中。它可能会影响您的结果。
  • @AmelieTurgeon - memberid 与客户的 clientid 一起存储在两个表中。请记住,出于示例目的,我已经硬编码了 memberid = "1"clientid = "1"。生产查询显然使用变量。也就是说,我会扔掉我所有的东西并重新开始。我看不出有其他出路。我的帖子中的最后一个 UPDATE ,该查询应该产生一个记录结果,但它没有。这就是让我感到困惑的地方。太疯狂了!
  • @Landslyde 然后不要忘记加入 clientid 和 memberid 以及日期。如果它仍然不起作用,请选择用于探索目的 p.* 和 h.*。你可能明白出了什么问题。