我是SQL的新手,如果我使用错误的术语并且我编写的代码是可怕的,那么道歉。
我正在尝试创建一个查询来输出每年每月的天数。我创建的测试表是datetest
:
startdate enddate
2105-12-16 2016-02-15
2017-01-01 2017-01-02
并使用下面粘贴的查询得到以下结果:
Year Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
2015 31 15 0 0 0 0 0 0 0 0 0 16
2017 4 0 0 0 0 0 0 0 0 0 0 0
我遇到的问题是,当日期范围超过两年时,结果会落在开始日期年份而非实际年份。
如果有人可以提供帮助,我会非常感激 感谢
查询
SELECT
year(startdate) AS Year,
SUM(GREATEST(datediff(least(CAST(CONCAT(YEAR(startdate), '-01-31') AS DATETIME),enddate),greatest(CAST(CONCAT(YEAR(startdate), '-01-01') AS DATETIME),startdate))+1,0))+SUM(GREATEST(datediff(least(CAST(CONCAT(YEAR(enddate), '-01-31') AS DATETIME),enddate),greatest(CAST(CONCAT(YEAR(enddate), '-01-01') AS DATETIME),startdate))+1,0)) AS "Jan",
SUM(GREATEST(datediff(least(CAST(CONCAT(YEAR(startdate), '-02-28') AS DATETIME),enddate),greatest(CAST(CONCAT(YEAR(startdate), '-02-01') AS DATETIME),startdate))+1,0))+SUM(GREATEST(datediff(least(CAST(CONCAT(YEAR(enddate), '-02-28') AS DATETIME),enddate),greatest(CAST(CONCAT(YEAR(enddate), '-02-01') AS DATETIME),startdate))+1,0)) AS "Feb",
SUM(GREATEST(datediff(least(CAST(CONCAT(YEAR(startdate), '-03-31') AS DATETIME),enddate),greatest(CAST(CONCAT(YEAR(startdate), '-03-01') AS DATETIME),startdate))+1,0))+SUM(GREATEST(datediff(least(CAST(CONCAT(YEAR(enddate), '-03-31') AS DATETIME),enddate),greatest(CAST(CONCAT(YEAR(enddate), '-03-01') AS DATETIME),startdate))+1,0)) AS "Mar",
SUM(GREATEST(datediff(least(CAST(CONCAT(YEAR(startdate), '-04-30') AS DATETIME),enddate),greatest(CAST(CONCAT(YEAR(startdate), '-04-01') AS DATETIME),startdate))+1,0))+SUM(GREATEST(datediff(least(CAST(CONCAT(YEAR(enddate), '-04-30') AS DATETIME),enddate),greatest(CAST(CONCAT(YEAR(enddate), '-04-01') AS DATETIME),startdate))+1,0)) AS "Apr",
SUM(GREATEST(datediff(least(CAST(CONCAT(YEAR(startdate), '-05-31') AS DATETIME),enddate),greatest(CAST(CONCAT(YEAR(startdate), '-05-01') AS DATETIME),startdate))+1,0))+SUM(GREATEST(datediff(least(CAST(CONCAT(YEAR(enddate), '-05-31') AS DATETIME),enddate),greatest(CAST(CONCAT(YEAR(enddate), '-05-01') AS DATETIME),startdate))+1,0)) AS "May",
SUM(GREATEST(datediff(least(CAST(CONCAT(YEAR(startdate), '-06-30') AS DATETIME),enddate),greatest(CAST(CONCAT(YEAR(startdate), '-06-01') AS DATETIME),startdate))+1,0))+SUM(GREATEST(datediff(least(CAST(CONCAT(YEAR(enddate), '-06-30') AS DATETIME),enddate),greatest(CAST(CONCAT(YEAR(enddate), '-06-01') AS DATETIME),startdate))+1,0)) AS "Jun",
SUM(GREATEST(datediff(least(CAST(CONCAT(YEAR(startdate), '-07-31') AS DATETIME),enddate),greatest(CAST(CONCAT(YEAR(startdate), '-07-01') AS DATETIME),startdate))+1,0))+SUM(GREATEST(datediff(least(CAST(CONCAT(YEAR(enddate), '-07-31') AS DATETIME),enddate),greatest(CAST(CONCAT(YEAR(enddate), '-07-01') AS DATETIME),startdate))+1,0)) AS "Jul",
SUM(GREATEST(datediff(least(CAST(CONCAT(YEAR(startdate), '-08-31') AS DATETIME),enddate),greatest(CAST(CONCAT(YEAR(startdate), '-08-01') AS DATETIME),startdate))+1,0))+SUM(GREATEST(datediff(least(CAST(CONCAT(YEAR(enddate), '-08-31') AS DATETIME),enddate),greatest(CAST(CONCAT(YEAR(enddate), '-08-01') AS DATETIME),startdate))+1,0)) AS "Aug",
SUM(GREATEST(datediff(least(CAST(CONCAT(YEAR(startdate), '-09-30') AS DATETIME),enddate),greatest(CAST(CONCAT(YEAR(startdate), '-09-01') AS DATETIME),startdate))+1,0))+SUM(GREATEST(datediff(least(CAST(CONCAT(YEAR(enddate), '-09-30') AS DATETIME),enddate),greatest(CAST(CONCAT(YEAR(enddate), '-09-01') AS DATETIME),startdate))+1,0)) AS "Sep",
SUM(GREATEST(datediff(least(CAST(CONCAT(YEAR(startdate), '-10-31') AS DATETIME),enddate),greatest(CAST(CONCAT(YEAR(startdate), '-10-01') AS DATETIME),startdate))+1,0))+SUM(GREATEST(datediff(least(CAST(CONCAT(YEAR(enddate), '-10-31') AS DATETIME),enddate),greatest(CAST(CONCAT(YEAR(enddate), '-10-01') AS DATETIME),startdate))+1,0)) AS "Oct",
SUM(GREATEST(datediff(least(CAST(CONCAT(YEAR(startdate), '-11-30') AS DATETIME),enddate),greatest(CAST(CONCAT(YEAR(startdate), '-11-01') AS DATETIME),startdate))+1,0))+SUM(GREATEST(datediff(least(CAST(CONCAT(YEAR(enddate), '-11-30') AS DATETIME),enddate),greatest(CAST(CONCAT(YEAR(enddate), '-11-01') AS DATETIME),startdate))+1,0)) AS "Nov",
SUM(GREATEST(datediff(least(CAST(CONCAT(YEAR(startdate), '-12-31') AS DATETIME),enddate),greatest(CAST(CONCAT(YEAR(startdate), '-12-01') AS DATETIME),startdate))+1,0))+SUM(GREATEST(datediff(least(CAST(CONCAT(YEAR(enddate), '-12-31') AS DATETIME),enddate),greatest(CAST(CONCAT(YEAR(enddate), '-12-01') AS DATETIME),startdate))+1,0)) AS "Dec"
from datetest
GROUP BY year(startdate)
答案 0 :(得分:1)
所以我知道你没有使用sql-server查看你的语法,所以这个概念可能对你有用,取决于你拥有的rdbms。但是这个概念是创建一个两个日期之间差异最大的计数表,然后使用它连接到原始表并将日期范围展平为单个行,然后简单地将该信息转回。
DECLARE @Table AS TABLE (startdate DATETIME, enddate DATETIME)
INSERT INTO @Table (startdate, enddate) VALUES ('2015-12-16','2016-02-15'),('2017-01-01','2017-01-02')
;WITH cteTally as (
SELECT MAX(DATEDIFF(day,startdate,enddate)) - 1 as Tally
FROM
@Table
UNION ALL
SELECT Tally - 1
FROM
cteTally
WHERE
Tally - 1 >= 0
)
, cteDates AS (
SELECT
DATEADD(day,c.Tally,t.startdate) as date
,YEAR(DATEADD(day,c.Tally,t.startdate)) as [Year]
,LEFT(DATENAME(month,DATEADD(day,c.Tally,t.startdate)),3) as [Month]
FROM
@Table t
INNER JOIN cteTally c
ON DATEDIFF(day,t.startdate,t.enddate) - 1 >= c.Tally
)
SELECT *
FROM
cteDates
PIVOT (
COUNT([date])
for [Month] IN ([Jan],[Feb],[Mar],[Apr],[May],[Jun],[Jul],[Aug],[Sep],[Oct],[Nov],[Dec])
) p
oracle,postgressql和sql-server支持这种类型的结构,而mysql则不支持。