样本表
CustomerId | VoucherId | CategoryId | StartDate | EndDate
-------------------------------------------------------------
10 | 1 | 1 | 2013-09-01| 2013-09-30
10 | 1 | 2 | 2013-09-01| 2013-09-30
11 | 2 | 1 | 2013-09-01| 2013-11-30
11 | 2 | 2 | 2013-09-01| 2013-11-30
11 | 2 | 3 | 2013-09-01| 2013-11-30
10 | 3 | 1 | 2013-10-01| 2013-12-31
10 | 3 | 2 | 2013-10-01| 2013-12-31
11 | 4 | 1 | 2013-12-01| 2014-04-30
在上面的样本记录中,我想找出客户代金券所涵盖的总月数
我需要
形式的输出CustomerId | Months
--------------------
10 | 4
11 | 8
问题在于凭证可以为不同的CategoryIds提供多行...
我计算了凭证所涵盖的月份为DATEDIFF(MM,StartDate,EndDate)+ 1 ...
当我应用SUM(DATEDIFF(MM,StartDate,EndDate))GROUP BY VoucherId,StartDate,EndDate时 由于VoucherId ....的多行,我给出了错误的结果。
我得到这样的东西......
CustomerId | Months
--------------------
10 | 8
11 | 14
在这种情况下,CategoryId无用
由于
答案 0 :(得分:4)
实际上,在您的情况下(当每个类别的句点相等时),您可以使用此查询:
with cte as (
select distinct
CustomerId, StartDate, EndDate
from Table1
)
select CustomerId, sum(datediff(mm, StartDate, EndDate) + 1) as diff
from cte
group by CustomerId
<强> sql fiddle demo 强>
答案 1 :(得分:0)
您在查询中按不需要的列进行分组。
答案 2 :(得分:0)
试试这个:
SELECT
T.CustomerId,
T.VoucherId,
SUM(DATEDIFF(MM, T1.FirstStartDate, T1.LastEndDate)) AS Months
FROM #YourTable T
JOIN
(
SELECT
CustomerId,
VoucherId,
MIN(StartDate) AS FirstStartDate,
MAX(EndDate) AS LastEndDate
FROM #YourTable T1
GROUP BY CustomerId, VoucherId
) ON T.CustomerId = T1.CustomerId AND T.VoucherId = T1.VoucherId
这假设您在第一个开始日期和最后结束日期之间没有间隙。如果这样做,您可能需要编辑内部选择。但我们的想法是让内部选择确定你的日期范围(并忽略类别),然后让外部选择总结几个月。
答案 3 :(得分:0)
<强> sql fiddle demo 强>
这个SQL小提琴解决了您的顾虑。您需要生成一个日历表,以便您有一些东西可以加入您的日期。然后,您可以为每个客户计算不同的MonthYears。
create table test(
CustomerId int,
StartDate date,
EndDate date
)
insert into test
values
(10, '9/1/2013', '9/30/2013'),
(10, '9/1/2013', '9/30/2013'),
(11, '9/1/2013', '11/30/2013'),
(11, '9/1/2013', '11/30/2013'),
(11, '9/1/2013', '11/30/2013'),
(10, '10/1/2013', '12/31/2013'),
(10, '10/1/2013', '12/31/2013'),
(11, '12/1/2013', '4/30/2014')
create table calendar(
MY varchar(10),
StartDate date,
EndDate date
)
insert into calendar
values
('9/2013', '9/1/2013', '9/30/2013'),
('10/2013', '10/1/2013', '10/31/2013'),
('11/2013', '11/1/2013', '11/30/2013'),
('12/2013', '12/1/2013', '12/31/2013'),
('1/2014', '1/1/2014', '1/31/2014'),
('2/2014', '2/1/2014', '2/28/2014'),
('3/2014', '3/1/2014', '3/31/2014'),
('4/2014', '4/1/2014', '4/30/2014')
select
t.CustomerId,
count(distinct c.MY)
from
test t
inner join calendar c
on t.StartDate <= c.EndDate
and t.EndDate >= c.StartDate
group by
t.CustomerId