2017-03-16 94 views
1

我工作了幾個小時纔得到我想要的結果,但我的SQL代碼卻沒有運氣。我試圖從一個表中選擇所有記錄,並從其他表中匹配記錄。從一個表中選擇所有記錄並從其他表中匹配記錄

請參閱現場示例here。從上面的例子

url_id short_url campaign Clicks 
1  test1  campaign1 2 
2  test2  campaign2 2 

SQL代碼:

SELECT u.url_id, u.short_url, c.campaign, Count(*) AS Clicks 
FROM (urls u LEFT JOIN log l ON l.url_id = u.url_id) LEFT JOIN campaign c ON u.campaign_id = c.campaign_id 
WHERE (((DATE_FORMAT(l.date_time, '%Y-%m-%d')) Between '2017-03-14' And '2017-03-17')) 
GROUP BY u.url_id, u.short_url, c.campaign; 

我想對結果是這樣的。包含來自urls表的所有記錄。

url_id short_url campaign Clicks 
1  test1  campaign1 2 
2  test2  campaign2 2 
3  test3  campaign1 0 
4  test4     0 

我試圖WHERE子句中加入l.url_id is null但點擊具有1,而不是零(0)

url_id short_url campaign Clicks 
1  test1  campaign1 2 
2  test2  campaign2 2 
3  test3  campaign1 1 
4  test4     1 

SQL代碼從上述樣品的值:

SELECT u.url_id, u.short_url, c.campaign, Count(*) AS Clicks 
FROM (urls u LEFT JOIN log l ON l.url_id = u.url_id) LEFT JOIN campaign c ON u.campaign_id = c.campaign_id 
WHERE (((DATE_FORMAT(l.date_time, '%Y-%m-%d')) Between '2017-03-14' And '2017-03-17')) or l.url_id is null 
GROUP BY u.url_id, u.short_url, c.campaign; 

回答

2

這可能是概念上容易只是聚集在log表,因爲這是正在生成點擊次數,而不是其他表。沿着這些線路的走向,我們可以嘗試以下查詢:

SELECT t1.url_id, 
     t1.short_url, 
     COALESCE(t2.campaign, 'NA') AS campaign, 
     COALESCE(t3.num_clicks, 0) AS Clicks 
FROM urls t1 
LEFT JOIN campaign t2 
    ON t1.campaign_id = t2.campaign_id 
LEFT JOIN 
(
    SELECT url_id, COUNT(*) AS num_clicks 
    FROM log 
    WHERE DATE_FORMAT(date_time, '%Y-%m-%d') BETWEEN '2017-03-14' AND '2017-03-17' 
    GROUP BY url_id 
) t3 
    ON t1.url_id = t3.url_id; 

輸出:

enter image description here

演示在這裏:

Rextester

+1

非常感謝。它的工作原理也比使用'is null'更快。 – jaypabs

+0

@jaypabs我真的很驚訝,它比其他兩個答案快,但從代碼維護的角度來看,我認爲我的查詢更容易閱讀和維護。如果你需要在查詢中添加一個非聚合列,這很簡單,但在你原來的方法中,情況可能不是這樣。 –

+0

是的。這比兩個答案快得多,我爲此感謝你。 – jaypabs

2

使用COUNT(l.id)代替COUNT(*)

WHERE條款中加上l.date_time IS NULL

檢查http://rextester.com/YOX73980

SELECT u.url_id, u.short_url, c.campaign, Count(l.id) AS Clicks 
FROM urls u 
LEFT JOIN log l ON l.url_id = u.url_id 
LEFT JOIN campaign c ON u.campaign_id = c.campaign_id 
WHERE l.date_time IS NULL OR (DATE_FORMAT(l.date_time, '%Y-%m-%d')) Between '2017-03-14' And '2017-03-17' 
GROUP BY u.url_id, u.short_url, c.campaign; 
1
SELECT u.url_id, u.short_url, c.campaign, Count(c.campaign_id) AS Clicks 
FROM urls u LEFT JOIN log l ON l.url_id = u.url_id 
LEFT JOIN campaign c ON u.campaign_id = c.campaign_id 
AND (((DATE_FORMAT(l.date_time, '%Y-%m-%d')) Between '2017-03-14' And '2017-03-17')) 
GROUP BY u.url_id, u.short_url, c.campaign; 

檢查Demo

相關問題