2017-03-16 59 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

相关问题