2013-04-03 53 views
1

我有一个表产品有以下的列SQL查询:集团按月份及年份针对这种情况

ProductId Name RegistrationDate UnregistrationDate 
1   AB 2013-01-01  2013-03-01 
2   CD 2013-01-10  2013-03-13 

我想获得注册产品每一个列表一年中的每个月。

示例:年份,月份以及注册和未注销经销商的数量。

Year Month RegisteredProucts 
2013 2   35 
2013 3   45(includes products even registered before March 2013) 

我写的follwing存储过程来找到注册的产品为一个月: &它的工作原理:

@Begin Time = First Day of the Month 
@End Time = Last Day of the Month 


select COUNT(DISTINCT P.ProductId) as RegisteredProducts from Product P  
where ((P.RegisteredDate < @EndTime) 
AND (P.UnregisteredDate > @EndTime)) 

然后我写了下面的查询,但它似乎组的结果由RegisteredDate 。 我想知道我可以在每个月末 将注册产品(非注册产品)分组一年吗?

select YEAR(P.RegisteredDate) AS [YEAR],MONTH(P.RegisteredDate) AS [MONTH],  COUNT(DISTINCT P.ProductId) as RegisteredProducts from Product P  
where ((P.RegisteredDate < @EndTime) 
AND (P.UnregisteredDate > @EndTime)) 
group by YEAR(D.RegisteredDate), MONTH(D.RegisteredDate) 

回答

1
WITH months (mon) AS 
     (
     SELECT CAST('2013-01-01' AS DATE) AS mon 
     UNION ALL 
     SELECT DATEADD(month, 1, mon) 
     FROM months 
     WHERE mon < DATEADD(month, -1, GETDATE()) 
     ) 
SELECT mon, COUNT(productId) 
FROM months 
LEFT JOIN 
     registeredProducts 
ON  registrationDate < DATEADD(month, 1, mon) 
     AND (unregistrationDate >= mon OR unregistrationDate IS NULL) 
GROUP BY 
     mon 
+0

谢谢!这个解决方案有效你能告诉我如果我想动态地将月份限制到当前月份,我可以做些什么。例如:由于2013年4月仍在进行中,我只想在2013年3月前获得产品,而不是2013年3月以后。 – CodeNinja

+0

@SQL:查看帖子更新 – Quassnoi

1
; with months as 
     (
     select cast('2013-01-01' as date) as dt 
     union all 
     select dateadd(month, 1, dt) 
     from months 
     where dt < '2014-01-01' 
     ) 
select * 
from months m 
cross apply 
     (
     select count(*) as ProductCount 
     from Product p 
     where p.RegistrationDate < dateadd(month, 1, m.dt) and 
       (
        UnregistrationDate is null 
        or UnregistrationDate >= m.dt 
       ) 
     ) p 

Example at SQL Fiddle.

+0

感谢您花时间在SQL小提琴中演示它!解决方案也可以工作!直到现在我还没有使用交叉应用。你能告诉我是否有办法动态限制月份数量。例如:我只想在2013年3月前获得注册产品,但不会超出此限 – CodeNinja