Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用SQL根据不同月份聚合年度数据_Sql_Sql Server - Fatal编程技术网

使用SQL根据不同月份聚合年度数据

使用SQL根据不同月份聚合年度数据,sql,sql-server,Sql,Sql Server,我有一个“金额”表,其中有客户每月的付款。每一位顾客支付的每一笔款项都有一排。我想从他们第一次付款的月份开始,每年汇总他们的付款。例如,在下表中,对于userID 132,我希望将其从2019年第9个月到2020年第8个月(一整年)的付款合计为一行,然后再从2020年第9个月到下一个月作为另一行 基本上,我希望根据用户加入的月份将每年的用户数量作为行。我不知道如何使用SQL聚合这些数据,希望您能在这里提供帮助 示例表(如果更简单,我可以将年和月列合并为原始数据本身中的日期列)> 示例输出(此处的

我有一个“金额”表,其中有客户每月的付款。每一位顾客支付的每一笔款项都有一排。我想从他们第一次付款的月份开始,每年汇总他们的付款。例如,在下表中,对于userID 132,我希望将其从2019年第9个月到2020年第8个月(一整年)的付款合计为一行,然后再从2020年第9个月到下一个月作为另一行

基本上,我希望根据用户加入的月份将每年的用户数量作为行。我不知道如何使用SQL聚合这些数据,希望您能在这里提供帮助

示例表(如果更简单,我可以将年和月列合并为原始数据本身中的日期列)>

示例输出(此处的“年周期”列仅用于指示自用户加入以来,总数属于哪一年)。>

参考资料-

  • ,
  • 使用下面的
    CTE
    获得您想要的结果

    Get date(获取日期)列以获取每个用户第一次使用CTE的最小日期
    AmountWithDate

    然后使用先前的
    CTE
    AmountWithDate创建另一个
    CTE
    AmountWithDate
    从用户的第一笔交易中获取
    years
    。必须使用
    over(按…分区)

    然后使用
    AmountWithYearDifference
    groupby
    dt
    SUM(Amount)
    获得所需的输出

    ;WITH AmountWithDate AS (
        SELECT *, DATEFROMPARTS(year, month, 1) AS dt 
        FROM Amounts
    )
    , AmountWithYearDifference AS (
        SELECT *, DATEDIFF(MONTH, (min(dt) over(partition by userid)), dt) / 12 AS years
        FROM AmountWithDate
    )
    SELECT userid, 
            min(dt) AS dt, DATEPART(MONTH, MIN(dt)) as month, 
            DATEPART(YEAR, MIN(dt)) as year, 
            sum(Amount)
    FROM AmountWithYearDifference
    GROUP BY userid, years
    

    编辑如果您已经有了
    date
    列,则无需先有
    CTE
    ,您可以直接使用第二个
    CTE
    。我假设您的
    date
    列名是
    dt

    ;WITH AmountWithYearDifference AS (
        SELECT *, DATEDIFF(MONTH, (min(dt) over(partition by userid)), dt) / 12 AS years
        FROM Amounts
    )
    SELECT userid, 
            min(dt) AS dt, DATEPART(MONTH, MIN(dt)) as month, 
            DATEPART(YEAR, MIN(dt)) as year, 
            sum(Amount)
    FROM AmountWithYearDifference
    GROUP BY userid, years
    
    如果您不熟悉
    CTE
    并且希望使用
    内部sql查询
    ,那么您可以编写如下查询。只需从
    CTE
    内部查询中写入
    query
    ,如下所示

    SELECT userid, 
            min(dt) AS dt, DATEPART(MONTH, MIN(dt)) as month, 
            DATEPART(YEAR, MIN(dt)) as year, 
            sum(Amount)
    FROM (
        SELECT *, DATEDIFF(MONTH, (min(dt) over(partition by userid)), dt) / 12 AS years
        FROM Amounts
    )
    GROUP BY userid, years
    
    您可以使用为每个用户生成一个序列号,然后将每12个作为1个周期分组

    select userId, cycle, sum(amount)
    from
    (
        select *, 
               cycle = (row_number() over (partition by userId 
                                               order by year, month) - 1) / 12 + 1
        from   Amounts
    ) t
    group by userId, cycle
    

    请添加以下内容。并且不要使用数据的图像,将其粘贴为纯文本。从表组中按年选择总和(值)、年、月,month@astentx谢谢我已经做了你建议的编辑。@WalterVehoeven我认为这不会给我想要的结果。我想要一行指示前12个月的总和(值),然后另一行指示未来12个月的总和,基于每个用户的数据开始的月份。您需要向我们显示您的预期结果和您的尝试。嘿!谢谢你。我是SQL新手,所以不太熟悉CTE。我看到您正在从第一个CTE创建一个日期列。如果我已经在基表中创建了所需的日期列,而不是月份和年份列,这会使工作更容易吗?当然,有日期列将是一个优势。您只需要一个
    CTE
    。我添加了几个链接供参考。CTE是一种临时表。如果加入
    后,
    OP
    每个月都有一条且只有一条记录
    ,则只有该代码有效。
    
    SELECT userid, 
            min(dt) AS dt, DATEPART(MONTH, MIN(dt)) as month, 
            DATEPART(YEAR, MIN(dt)) as year, 
            sum(Amount)
    FROM (
        SELECT *, DATEDIFF(MONTH, (min(dt) over(partition by userid)), dt) / 12 AS years
        FROM Amounts
    )
    GROUP BY userid, years
    
    select userId, cycle, sum(amount)
    from
    (
        select *, 
               cycle = (row_number() over (partition by userId 
                                               order by year, month) - 1) / 12 + 1
        from   Amounts
    ) t
    group by userId, cycle