在SQL中获取每一天的数据

时间:2012-10-22 00:22:04

标签: mysql sql date

我目前有以下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肯定是杀死结果的那个。

3 个答案:

答案 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)

** Thorpe Obazee

更新
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。我们也不应在DAYOFMONTHGROUP 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]

我个人不喜欢使用派生表,因为我使用更原生的连接看到了更好的性能,但是,我通常使用数百万行的数据集。