我目前有以下SQL语句
MySQL查询:
SELECT
c.day,
COUNT(*)
FROM
calendar c
JOIN
visitors d
ON DAYOFMONTH(d.created) = c.day
WHERE
c.day BETWEEN DAYOFMONTH('2012-10-01') AND DAYOFMONTH('2012-10-31')
AND
site_id = 16
GROUP BY
DAYOFMONTH(d.created)
ORDER BY
DAYOFMONTH(d.created)
我的表格:
Calendar
id | day
---------
1 | 1
2 | 2
3 | 3
...
31 | 31
Visitors
id | site_id | created
-----------------------------------
1 | 16 | 2012-10-18 11:14:39
2 | 16 | 2012-10-18 11:15:17
3 | 11 | 2012-10-18 11:49:14
4 | 11 | 2012-10-18 11:49:43
5 | 16 | 2012-10-19 11:54:37
6 | 1 | 2012-10-19 05:56:31
7 | 2 | 2012-10-19 05:57:56
我已经按照answer的规定创建了表格,日历,但我似乎仍然得到相同的信息。我只得到我有数据的日期。
day | COUNT(*)
---------------------
18 | 2
19 | 1
我还需要在没有数据的日期检索0
。
更新:
I tried this:
SELECT *
FROM calendar c
LEFT JOIN visitors d
ON DAYOFMONTH(d.created) = c.day
和
SELECT *
FROM calendar c
LEFT JOIN visitors d
ON DAYOFMONTH(d.created) = c.day
WHERE site_id = 16
我可以确认site_id = 16
肯定是杀死结果的那个。
答案 0 :(得分:1)
使用LEFT JOIN
代替INNER JOIN
SELECT ...
FROM calendar c
LEFT JOIN visitors d
ON DAYOFMONTH(d.created) = c.day
WHERE...
INNER JOIN
仅检索在另一个表上至少有一个匹配的行,而LEFT JOIN
检索左侧表中定义的所有行,无论它是匹配还是没有其他表格。
更新1
SELECT c.day,
COUNT(*)
FROM calendar c
LEFT JOIN
(
SELECT *
FROM visitors
WHERE site_id = 16
) d ON DAYOFMONTH(d.created) = c.day
WHERE c.day BETWEEN DAYOFMONTH('2012-10-01') AND DAYOFMONTH('2012-10-31')
GROUP BY DAYOFMONTH(c.day)
ORDER BY DAYOFMONTH(c.day)
更新
SELECT c.day,
COUNT(site_id)
FROM calendar c
LEFT JOIN
(
SELECT *
FROM visitors
WHERE site_id = 16
) d ON DAYOFMONTH(d.created) = c.day
WHERE c.day BETWEEN DAYOFMONTH('2012-10-01') AND DAYOFMONTH('2012-10-31')
GROUP BY c.day
ORDER BY c.day
我们无法使用COUNT(*)
,因为它每天都会返回1
。我们也不应在DAYOFMONTH
和GROUP BY
的c.day使用ORDER BY
,因为它已经是我们需要的。
答案 1 :(得分:0)
正如最后一张海报所说,使用LEFT JOIN但是要澄清。
想象一下,您的Calendar表是LEFT表,Visitors表是正确的表
使用INNER JOIN
FROM Calendar c
INNER JOIN Visitors v
ON c.Date = v.Date
左侧和右侧都必须匹配。
LEFT JOIN
FROM Calendar c
LEFT JOIN Visitors v
ON c.Date = v.Date
您将从LEFT表(日历)返回所有记录,并且只有与您的RIGHT表(访问者)匹配的记录,对于没有任何匹配访问者数据的所有日历日期,您将留下NULL(除非当然你用COALESCE之类的东西处理这个问题
使用RIGHT JOIN
FROM Calendar c
RIGHT JOIN Visitors v
ON c.Date = v.Date
您将从您的右表(访客)返回所有记录,并且只返回与您的左表(日历)匹配的记录,您将获得未找到匹配项的列值的NULLS,这将捕获您拥有的任何记录访客数据因为,即使日期不在日历表中。
希望有所帮助。
凯文
答案 2 :(得分:0)
回答这个问题的另一个建议就是移动
WHERE site_id = 16
进入JOIN,例如,
SELECT
c.[Day]
,COUNT(v.[id])
FROM TestDB.dbo.Calendar c
LEFT JOIN TestDB.dbo.Visitor v
ON c.[Day] = DATEPART(d,v.Created)
AND v.[SiteID] = 16
GROUP BY c.[Day]
ORDER BY c.[Day]
我个人不喜欢使用派生表,因为我使用更原生的连接看到了更好的性能,但是,我通常使用数百万行的数据集。