我遇到了一个问题,在多次尝试失败后我似乎无法弄清楚。
我有三个表,我需要为某些报告进行连接,而在第 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/