2010-02-16 53 views
6

数据:约2010年1月如何获得每天值在一个月

values date 
14 1.1.2010 
20 1.1.2010 
10 2.1.2010 
7 4.1.2010 
... 

样本查询应该得到31行。每天一次。并且值将被添加。现在我可以用31个查询来做到这一点,但我希望这可以与一个查询一起工作。可能吗?

结果:

1. 34 
2. 10 
3. 0 
4. 7 
... 
+0

欢迎来到SO伊娃。我认为你需要添加一些关于你在查询什么的更多细节,以及如何? – 2010-02-16 17:15:28

+0

需要更多的细节......你在用什么语言?这是什么系统? – Mala 2010-02-16 17:17:18

+0

你的日期栏的类型是什么?它是DATE还是VARCHAR? – 2010-02-16 17:21:09

回答

10

这在SQL中实际上很难做到。做到这一点的方法之一是与UNION承滴盘长的select语句生成从1数到31。这表明了原则,但我停在4清晰度:

SELECT MonthDate.Date, COALESCE(SUM(`values`), 0) AS Total 
FROM (
    SELECT 1 AS Date UNION ALL 
    SELECT 2 UNION ALL 
    SELECT 3 UNION ALL 
    SELECT 4 UNION ALL 
    -- 
    SELECT 28 UNION ALL 
    SELECT 29 UNION ALL 
    SELECT 30 UNION ALL 
    SELECT 31) AS MonthDate 
LEFT JOIN Table1 AS T1 
ON MonthDate.Date = DAY(T1.Date) 
AND MONTH(T1.Date) = 1 AND YEAR(T1.Date) = 2010 
WHERE MonthDate.Date <= DAY(LAST_DAY('2010-01-01')) 
GROUP BY MonthDate.Date 

这可能是更好的使用表来存储这些值,并加入它。

结果:

1, 34 
2, 10 
3, 0 
4, 7 
5

鉴于一些约会,你有没有数据,就需要填补空白。其中一种方法是预先填写您需要的所有日期的日历表,然后加入。 如果您希望结果显示日期数字,就像您在问题中显示的那样,您也可以将其作为标签预先填入日历中。

您可以将数据表日期字段加入到日历表的日期字段中,按字段进行分组和总和值。您可能需要为涵盖的日期范围指定限制。

所以,你可能有:

CREATE TABLE Calendar (
    label varchar, 
    cal_date date, 
    primary key (cal_date) 
) 

查询:

SELECT 
    c.label, 
    SUM(d.values) 
FROM 
    Calendar c 
JOIN 
    Data_table d 
ON d.date_field = c.cal_date 
WHERE 
    c.cal_date BETWEEN '2010-01-01' AND '2010-01-31' 
GROUP BY 
    d.date_field 
ORDER BY 
    d.date_field 

更新

我看你有没有日期时间,而不是日期。您可以在连接中使用MySQL DATE()函数,但这可能不是最佳选择。另一种方法是让日历表中的开始和结束时间定义每天的“时间段”。

0

如果我理解比较模糊的问题正确,你想知道的记录一个月内的每个日期的数量。如果这是真的,这里是你如何能做到这一点:

SELECT COUNT(value_column) FROM table WHERE date_column LIKE '2010-01-%' GROUP BY date_column 
+0

date_column有时没有设置 – NineCattoRules 2017-11-05 15:17:56

+1

@NineCattoRules除非你是七年前的OP,我不知道你怎么知道这一点。如果是这种情况,可以很容易地修改查询以进行调整。 – ceejayoz 2017-11-05 17:01:44

+0

在这个问题:“......每天...”,并在'results'(从OP)有'3。 0' – NineCattoRules 2017-11-05 17:09:11

1

要使用SQL,你可以做到这一点(在MySQL的例子)动态获取的日期范围内的日期:

创建一个表来保存数0到9

CREATE TABLE ints (i tinyint(4)); 

insert into ints (i) 
values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); 

运行,像这样的查询:

select ((curdate() - interval 2 year) + interval (t.i * 100 + u.i * 10 + v.i) day) AS Date 
from 
    ints t 
    join ints u 
    join ints v 
having Date between '2015-01-01' and '2015-05-01' 
order by t.i, u.i, v.i 

这将产生之间的所有日期2015年1月1日和2015年5月1日。

Output 
2015-01-01 
2015-01-02 
2015-01-03 
2015-01-04 
2015-01-05 
2015-01-06 
... 
2015-05-01 

查询联接表整数3次,并得到一个递增的数字(0到999)。然后它将这个数字作为从某个特定日期开始的日间间隔,在这种情况下是2年前的日期。使用上面的示例可以获得2年前和1000天前的任何日期范围。 要生成,生成日期为1000多名直接照搬加入整数表一次,以允许高达10000天的范围,等等的查询。

1

这个工作对我来说...它的查询我在其他网站上发现的修改。 “INTERVAL 1 MONTH”子句可确保获得当前月份数据,包括没有匹配的天数为零。更改为“区间2月”得到最后几个月的数据,等等

我有一个名为“有效载荷”与列“时间戳”表 - 那么IM在加入时间戳列到动态生成的日期,它铸造以便在ON子句中匹配日期。


SELECT `calendarday`,COUNT(P.`timestamp`) AS `cnt` FROM 
(SELECT @tmpdate := DATE_ADD(@tmpdate, INTERVAL 1 DAY) `calendarday` 
    FROM (SELECT @tmpdate := 
     LAST_DAY(DATE_SUB(CURDATE(),INTERVAL 1 MONTH))) 
     AS `dynamic`, `payload`) AS `calendar` 
LEFT JOIN `payload` P ON DATE(P.`timestamp`) = `calendarday` 
GROUP BY `calendarday` 
相关问题