数据:
values date
14 1.1.2010
20 1.1.2010
10 2.1.2010
7 4.1.2010
...
关于2010年1月的样本查询应该得到31行。每天一个。值得加入。现在我可以用31个查询做到这一点,但我希望这可以用一个。有可能吗?
结果:
1. 34
2. 10
3. 0
4. 7
...
答案 0 :(得分:11)
这在SQL中实际上非常难以实现。一种方法是使用一个带有UNION ALL的长选择语句来生成从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
答案 1 :(得分: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()函数,但这可能不是最佳的。另一种方法是在Calendar表中定义每天的“时间段”的开始和结束时间。
答案 2 :(得分: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天的任何日期范围。 要生成生成日期超过1,000天的查询,只需再次加入ints表以允许最多10,000天的范围,依此类推。
答案 3 :(得分:1)
这对我有用......它是我在另一个网站上找到的查询的修改。 “INTERVAL 1 MONTH”子句确保我获得当前月份数据,包括没有命中数天的零。将其更改为“INTERVAL 2 MONTH”以获取上个月的数据等
我有一个名为“payload”的表,其中包含“timestamp”列 - 然后我将时间戳列加到动态生成的日期,然后将其转换为使日期在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`
答案 4 :(得分:0)
如果我正确理解了这个相当含糊的问题,你想知道一个月内每个日期的记录数。如果这是真的,那么你可以这样做:
SELECT COUNT(value_column) FROM table WHERE date_column LIKE '2010-01-%' GROUP BY date_column