3 个表上的 MySQL INNER/LEFT JOIN,其中第 3 个表中的记录可能不存在

标签 mysql join left-join inner-join

我遇到了一个问题,在多次尝试失败后我似乎无法弄清楚。

我有三个表,我需要为某些报告进行连接,而在第 3 个表中,一条记录可能不存在。但是,如果第三张表中的记录不存在,我需要为来自第三张表的数据报告一个空值,并获取所有符合其他条件的记录。

精简到相关列,这里是表结构:

成员 - 此表包含注册到网站的所有成员

| memberId  | insertDate          |
| ==========|=====================|
| 1         | 2013-08-01 18:18:16 |
| 2         | 2013-08-02 18:18:16 |
| 3         | 2013-08-03 18:18:16 |
| 4         | 2013-08-04 18:18:16 |
| 5         | 2013-08-05 18:18:16 |

registration_steps - 此表包含注册过程的进度以及注册是否完成

| memberId  | completed |
| ==========|===========|
| 1         | 1         |
| 2         | 1         |
| 3         | 1         |
| 4         | 0         |
| 5         | 1         |

购买 - 这张表包含,嗯..购买

| memberId  | insertDate          |
| ==========|=====================|
| 1         | 2013-08-02 18:18:16 |
| 1         | 2013-08-03 17:18:16 |
| 1         | 2013-08-03 18:18:16 |
| 5         | 2013-08-07 18:18:16 |

这是我到目前为止提出的查询:

SELECT `m`.`memberId`,
       DATE(`m`.`insertDate`) AS `regDate`,
       COUNT(`p`.`memberId`) AS `totalTransactions`,
       DATE(MIN(`p`.`insertDate`)) AS `firstPurchaseDate`,
       DATE(MAX(`p`.`insertDate`)) AS `latestPurchaseDate`,
       DATEDIFF(DATE(MIN(`p`.`insertDate`)), DATE(`m`.`insertDate`)) AS `daysBetweenRegAndFirstPurchase`
  FROM `db`.`members` `m`
       INNER JOIN `db`.`registration_steps` `r` ON `m`.`memberId` = `r`.`memberId` 
       INNER JOIN `db`.`purchases` `p` ON `m`.`memberId` = `p`.`memberId`
 WHERE `m`.`insertDate` BETWEEN '2013-07-01 00:00:00' AND '2013-07-31 23:59:59'
   AND `r`.`completed` = 1
GROUP BY `m`.`memberId`
;

它显示了我想要的所有内容,但缺少餐 table 购买记录的成员(member)。

这是我得到的:

| memberId  | regDate             | totalTransactions | firstPurchaseDate   | latestPurchaseDate  | daysBetweenRegAndFirstPurchase |
| ==========|=====================|===================|=====================|=====================|================================|
| 1         | 2013-08-01 18:18:16 | 3                 | 2013-08-02 18:18:16 | 2013-08-03 18:18:16 | 1                              |
| 5         | 2013-08-05 18:18:16 | 1                 | 2013-08-07 18:18:16 | 2013-08-07 18:18:16 | 2                              |

但我需要的是:

| memberId  | regDate             | totalTransactions | firstPurchaseDate   | latestPurchaseDate  | daysBetweenRegAndFirstPurchase |
| ==========|=====================|===================|=====================|=====================|================================|
| 1         | 2013-08-01 18:18:16 | 3                 | 2013-08-02 18:18:16 | 2013-08-03 18:18:16 | 1                              |
| 2         | 2013-08-02 18:18:16 | 0                 | NULL                | NULL                | -1                             |
| 3         | 2013-08-03 18:18:16 | 0                 | NULL                | NULL                | -1                             |
| 5         | 2013-08-05 18:18:16 | 1                 | 2013-08-07 18:18:16 | 2013-08-07 18:18:16 | 2                              |

为了实现这个,我尝试把第二个inner join改成left join,left outer join,把where条件放到第一个inner join条件上。但是,我无法获得想要的结果。 (必须承认我打断了一些可能是正确的(?)运行时间非常长的查询(但实际情况下的成员总数约为 20k)。)

有人吗?

提前致谢!

最佳答案

要从 member 表中获取所有结果,您需要 left join 其他表并为 添加 group by成员表。

示例

FROM `db`.`members` `m`
       LEFT OUTER JOIN `db`.`registration_steps` `r` ON `m`.`memberId` = `r`.`memberId` 
       LEFT OUTER JOIN `db`.`purchases` `p` ON `m`.`memberId` = `p`.`memberId`

左 [外]

指定左表中所有不满足连接条件的行都包含在结果集中,并且除了内连接返回的所有行外,其他表的输出列都设置为NULL。

关于3 个表上的 MySQL INNER/LEFT JOIN,其中第 3 个表中的记录可能不存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18415080/

相关文章:

php - 删除上传到mysql数据库的csv文件中的第一行

PHP/MySQL/jQuery/AJAX 类似 Twitter 的新闻提要更新

mysql - 具有多个连接的 MySQL 查询执行计划效率低下

join - Mondrian/OLAP 是连接大尺寸/集合的错误工具吗?

mysql - FluentMigrator 创建 Clob/文本

java - Java程序中导入CSV数据到mysql表

mysql - 连接 3 个子查询

MySQL LEFT JOIN 与 GROUP BY 和 WHERE IN(子查询)

php - 带有 LEFT JOIN 的嵌套 SELECT 语句

MySQL 问题 : LEFT JOIN on empty table