我必须计算每月的每日汽车数量 我尝试使用Datediff公式执行此操作 但是我也不能添加每个月的细分。
附加的脚本表:
create table TABLE_A(Code FLOAT,DateIn datetime,dateOut datetime,Garage varchar(30)
)
insert into Table_A (Code,DateIn,dateOut,Garage) values
('1','2018-06-07 00:00:00.000','2018-12-19 00:00:00.000','X'),
('2','2018-05-30 00:00:00.000','2018-12-19 00:00:00.000','Y'),
('3','2018-08-08 00:00:00.000','2018-11-18 00:00:00.000','Z'),
('4','2018-12-30 00:00:00.000','2018-12-30 00:00:00.000','Y'),
('5','2018-09-16 00:00:00.000','2018-10-19 00:00:00.000','Y'),
('6','2018-05-08 00:00:00.000','2018-08-28 00:00:00.000','Z'),
('7','2018-01-29 00:00:00.000','2018-07-31 00:00:00.000','Z'),
('8','2018-05-24 00:00:00.000','2018-09-10 00:00:00.000','X'),
('9','2018-05-02 00:00:00.000','2018-06-30 00:00:00.000','Y'),
('10','2018-07-05 00:00:00.000','2018-12-09 00:00:00.00','Z')
这是查询结果的结构,其结构应为:(列:年,月,车库-每天按天计算的车辆数量)
Year month X Y Z
2018 1
2018 2
2018 3
2018 4
2018 5
2018 6
2018 7
2018 8
2018 9
2018 10
2018 11
2018 12
感谢您的帮助。
答案 0 :(得分:0)
以下脚本仅在特定记录的所有DateIn和DateOut都在同一年(如2018年)时起作用。
Le年不考虑年份,但可以实施。
WITH Month_Wise_Day AS
(
-- Listing/selecting 12 month manually here
-- With number of day for that month
SELECT 1 M, 31 ND UNION ALL
SELECT 2 M, 28 UNION ALL SELECT 3 M,31 UNION ALL SELECT 4 M,30 UNION ALL SELECT 5 M,31 UNION ALL
SELECT 6 M,30 UNION ALL SELECT 7 M,31 UNION ALL SELECT 8 M,31 UNION ALL SELECT 9 M,30 UNION ALL
SELECT 10 M,31 UNION ALL SELECT 11 M,30 UNION ALL SELECT 12 M,31
)
SELECT A.Year, A.Month,
SUM(CASE WHEN A.Garage = 'X' THEN A.No_of_days ELSE 0 END) AS X,
SUM(CASE WHEN A.Garage = 'Y' THEN A.No_of_days ELSE 0 END) AS Y,
SUM(CASE WHEN A.Garage = 'Z' THEN A.No_of_days ELSE 0 END) AS Z
FROM
(
SELECT A.*,
B.M AS Month,
YEAR(A.DateIn) AS Year,
CASE
WHEN MONTH(A.DateIn) = MONTH(A.DateOut) THEN DATEDIFF(DD,DateIn,DateOut) +1
WHEN B.M = MONTH(DateIn) THEN B.ND - DAY(DateIn)+1
WHEN B.M = MONTH(DateOut) THEN DAY(DateOut)
ELSE ND
END No_of_days
FROM TABLE_A A
INNER JOIN Month_Wise_Day B ON B.M BETWEEN MONTH(DateIn) AND MONTH (DateOut)
)A
GROUP BY A.Year, A.Month
答案 1 :(得分:0)
您可以首先生成月份和年份的列表,然后可以将表加入该列表-
WITH MONTHS AS (SELECT 1 MNTHS
UNION ALL
SELECT 2
UNION ALL
SELECT 3
UNION ALL
SELECT 4
UNION ALL
SELECT 5
UNION ALL
SELECT 6
UNION ALL
SELECT 7
UNION ALL
SELECT 8
UNION ALL
SELECT 9
UNION ALL
SELECT 10
UNION ALL
SELECT 11
UNION ALL
SELECT 12),
YEAR AS (SELECT 2018 YEAR)
SELECT YEAR,
MNTHS,
SUM(CASE WHEN Garage = 'X' THEN 1 ELSE 0 END) AS X,
SUM(CASE WHEN Garage = 'Y' THEN 1 ELSE 0 END) AS Y,
SUM(CASE WHEN Garage = 'Z' THEN 1 ELSE 0 END) AS Z
FROM (SELECT * FROM MONTHS M CROSS JOIN YEAR Y) YEARS
LEFT JOIN TABLE_A T ON YEARS.MNTHS = MONTH(T.DateIn)
AND YEARS.YEAR = YEAR(T.DateIn)
GROUP BY YEAR(DateIn),
MONTH(DateIn),
MNTHS,
YEAR
ORDER BY YEAR,
MNTHS
这里是fiddle
答案 2 :(得分:0)
您可以使用递归子查询生成日期。
然后,您可以采用多种方法来计算摘要数据。一种简单的方法使用apply
:
with dates as (
select convert(date, '2018-01-01') as dte, 1 as lev
union all
select dateadd(month, 1, dte), lev + 1
from dates
where lev < 12
)
select year(d.dte), month(d.dte), s.*
from dates d outer apply
(select sum(case when a.Garage = 'X' then 1 else 0 end) as x,
sum(case when a.Garage = 'Y' then 1 else 0 end) as y,
sum(case when a.Garage = 'Z' then 1 else 0 end) as z
from table_a a
where a.datein <= d.dte and a.dateout >= d.dte
) s;
您的问题对确切的计算有点模糊。这样可以计算出每个月第一天每个车库中的汽车数量。
Here是db <>小提琴。
编辑:
您修改后的问题更加复杂,但是自从我开始回答:
with dates as (
select convert(date, '2018-01-01') as dte, 1 as lev
union all
select dateadd(month, 1, dte), lev + 1
from dates
where lev < 12
)
select year(d.dte), month(d.dte),
sum(case when a.Garage = 'X'
then datediff(day,
(case when a.datein < d.dte then d.dte else datein end),
(case when a.dateout >= dateadd(month, 1, d.dte) then eomonth(d.dte) else dateout end)
) + 1
else 0
end) as x_cardays,
sum(case when a.Garage = 'Y'
then datediff(day,
(case when a.datein < d.dte then d.dte else datein end),
(case when a.dateout >= dateadd(month, 1, d.dte) then eomonth(d.dte) else dateout end)
) + 1
else 0
end) as y_cardays,
sum(case when a.Garage = 'Z'
then datediff(day,
(case when a.datein < d.dte then d.dte else datein end),
(case when a.dateout >= dateadd(month, 1, d.dte) then eomonth(d.dte) else dateout end)
) + 1
else 0
end) as z_cardays
from (select d.*, day(eomonth(dte)) as days_in_month
from dates d
) d left join
table_a a
on a.datein < dateadd(month, 1, d.dte) and a.dateout >= d.dte
group by d.dte
order by d.dte;
与日期重叠有点棘手,但您绝对想对日期进行重叠。
请注意,这不是每天的平均值。如果需要平均值,可以除以d.days_in_month
。
Here是经过修改的db <>小提琴。
答案 3 :(得分:0)
以下查询应做您想做的事情,Recursive CTE
部分用于确定每个DayIn
和DayOut
之间的日期。有了完整的日期列表后,在主查询中,我们将进行条件汇总,以找出每月DISTINCT
个车库中的汽车数量
CREATE TABLE TABLE_A (Code FLOAT,DateIn DATETIME,dateOut DATETIME,Garage VARCHAR(30))
INSERT INTO Table_A (Code,DateIn,dateOut,Garage) VALUES
('1','2018-06-07 00:00:00.000','2018-12-19 00:00:00.000','X'),
('2','2018-05-30 00:00:00.000','2018-12-19 00:00:00.000','Y'),
('3','2018-08-08 00:00:00.000','2018-11-18 00:00:00.000','Z'),
('4','2018-12-30 00:00:00.000','2018-12-30 00:00:00.000','Y'),
('5','2018-09-16 00:00:00.000','2018-10-19 00:00:00.000','Y'),
('6','2018-05-08 00:00:00.000','2018-08-28 00:00:00.000','Z'),
('7','2018-01-29 00:00:00.000','2018-07-31 00:00:00.000','Z'),
('8','2018-05-24 00:00:00.000','2018-09-10 00:00:00.000','X'),
('9','2018-05-02 00:00:00.000','2018-06-30 00:00:00.000','Y'),
('10','2018-07-05 00:00:00.000','2018-12-09 00:00:00.00','Z')
/** Main Query Starts Here **/
;WITH CTE ([Code],[DateIn],[DateOut],[Garage]) AS (
SELECT [Code], [DateIn], [DateOut], [Garage]
FROM TABLE_A WHERE [DateIn] <= [DateOut]
UNION ALL
SELECT [Code], DATEADD(DAY, 1, [DateIn]), [DateOut], [Garage]
FROM CTE
WHERE [DateIn] < [DateOut])
SELECT
YEAR([DateIn]) AS [Year]
,MONTH([DateIn]) AS [Month]
,COUNT( DISTINCT CASE WHEN [Garage] = 'X' THEN T.t1 ELSE NULL END) AS X
,COUNT( DISTINCT CASE WHEN [Garage] = 'Y' THEN T.t1 ELSE NULL END) AS Y
,COUNT( DISTINCT CASE WHEN [Garage] = 'Z' THEN T.t1 ELSE NULL END) AS Z
FROM CTE
CROSS APPLY (VALUES (CONVERT(VARCHAR(4),YEAR([DateIn])) + CONVERT(VARCHAR(2),MONTH([DateIn])) + CONVERT(VARCHAR(20),[Code]))) AS T(t1)
GROUP BY YEAR([DateIn]), MONTH([DateIn])
ORDER BY [Year], [Month]
OPTION (MAXRECURSION 0)
结果如下,
Year Month X Y Z
2018 1 0 0 1
2018 2 0 0 1
2018 3 0 0 1
2018 4 0 0 1
2018 5 1 2 2
2018 6 2 2 2
2018 7 2 1 3
2018 8 2 1 3
2018 9 2 2 2
2018 10 1 2 2
2018 11 1 1 2
2018 12 1 2 1