【问题标题】:Sql Query : Group by Month & Year for this caseSql 查询:本案例按月和年分组
【发布时间】:2013-04-04 23:22:56
【问题描述】:

我有一个表 Product 包含以下列

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)

我写了以下存储过程来查找一个月的注册产品: 并且有效:

@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)

【问题讨论】:

    标签: sql-server sql-server-2008 tsql sql-server-2008-r2


    【解决方案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
    

    【讨论】:

    • 谢谢!该解决方案有效!如果我想动态地将星期一限制在当前月份,你能告诉我该怎么做吗?示例:我只想在 2013 年 3 月之前而不是 2013 年 3 月之后获得产品,因为 2013 年 4 月仍在进行中。
    【解决方案2】:
    ; 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.

    【讨论】:

    • 感谢您花时间在 SQL Fiddle 中演示它!该解决方案也有效!直到现在我还没有使用过交叉申请。你能告诉我是否有办法动态限制月数。示例:我现在只想在 2013 年 3 月之前获得注册产品,而不是超过这个时间
    猜你喜欢
    • 1970-01-01
    • 2011-07-21
    • 1970-01-01
    • 1970-01-01
    • 2020-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多