[英]MySQL INNER/LEFT JOIN on 3 tables, where records in 3rd table might not exist
我有一個問題,在一堆失敗的嘗試后我似乎無法弄清楚。
我有三個表需要為一些報告進行連接,而在第三個表中可能不存在記錄。 但是如果第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)。)
任何人?
提前致謝!
為了讓從所有的結果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`
左[外]
指定左表中不滿足連接條件的所有行都包含在結果集中,並且除了內連接返回的所有行之外,另一個表中的輸出列都設置為NULL。
(假設查詢中的日期范圍應介於2013-08而非2013-07之間)。 您需要將聯接與購買切換為外部聯接。 這包括沒有任何購買的會員......
left outer JOIN `purchases` `p` ON `m`.`memberId` = `p`.`memberId`
(用左連接替換內連接,您將得到正確的結果)
來自db
。 members
m
左加入db
。 registration_steps
r
ON m
。 memberId
= r
。 memberId
離開加入db
。 purchases
p
ON m
。 memberId
= p
。 memberId
或者您可以使用左連接單獨替換任何購買。
注意:左連接和左外連接都產生相同的結果,因此您可以使用其中任何一個。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.