我遇到了一些问题,在一系列尝试失败之后我似乎无法弄明白。
我有三个表需要为某些报告进行连接,而在第3个表中,可能不存在记录。但是如果第3个表中的记录不存在,我需要为来自第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`
;
它向我显示了我想要的所有内容,但是在桌面购买中缺少记录的成员。
这是我得到的:
| 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 |
为了实现这一点,我尝试将第二个内连接更改为左连接,左外连接并将where条件放入第一个内连接条件。但是,我无法获得理想的结果。 (必须承认我已经中断了一些非常长时间运行的查询,这些查询可能是正确的(?)但是(真实场景中成员的总数大约是20k)。)
任何?
提前致谢!
答案 0 :(得分:2)
要从member
表中获取所有结果,您需要left join
其他表格,并为group by
表格添加member
。
<强>示例强>
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`
LEFT [OUTER]
指定左表中不满足连接条件的所有行都包含在结果集中,并且除了内连接返回的所有行之外,另一个表中的输出列都设置为NULL。
答案 1 :(得分:1)
(假设查询中的日期范围应介于2013-08而非2013-07之间)。您需要将联接与购买切换为外部联接。这将包括没有任何购买的成员......
left outer JOIN `purchases` `p` ON `m`.`memberId` = `p`.`memberId`
答案 2 :(得分:0)
(用左连接替换内连接,你会得到正确的结果)
FROM db
。members
m
左加入db
。registration_steps
r
点击m
。memberId
= r
。memberId
离开加入db
。purchases
p
点击m
。memberId
= p
。memberId
或者您可以使用左连接替换任何购买。
注意:左连接和左外连接都会产生相同的结果,因此您可以使用其中任何一个。