SQL Server:每年选择前十大金额

时间:2018-08-22 18:19:10

标签: sql sql-server-2012

我有一份清单,我想按年度列出前十项。最好的方法是什么?我在SQL Server 2012上运行。

这是我到目前为止所拥有的:

SELECT DISTINCT
    YEAR(b.DateOfServiceLast)  AS 'Year',
    MONTH(b.DateOfServiceLast) AS 'Month',
    b.DiagnosisCode,
    SUM(c.Paid) OVER (PARTITION BY YEAR(b.DateOfServiceLast), MONTH(b.DateOfServiceLast), (b.DiagnosisCode)) AS 'Cost',
    ROW_NUMBER() OVER (PARTITION BY YEAR(b.DateOfServiceLast), MONTH(b.DateOfServiceLast) ORDER BY YEAR(b.DateOfServiceLast), MONTH(b.DateOfServiceLast)) AS 'Row'
FROM
    MO_CMTExtract.dbo.ProfessionalClaim a
LEFT JOIN
    MO_CMTExtract.dbo.ProfessionalClaimDetail b ON a.ProfessionalClaimID = b.ProfessionalClaimID
LEFT JOIN
    MO_CMTExtract.dbo.ProfessionalClaimDetailMoney c ON b.ProfessionalClaimDetailID = c.ProfessionalClaimDetailID
ORDER BY
    YEAR(b.DateOfServiceLast),
    MONTH(b.DateOfServiceLast),
    b.DiagnosisCode,
    Row, Cost;

2 个答案:

答案 0 :(得分:1)

使用WITH TIES是一种方法。我将查询保持不变,但将其包装在CTE中并删除了ORDER BY。然后,我们对那个WITH TIES使用CTE

WITH CTE AS(
SELECT DISTINCT
        YEAR(b.DateOfServiceLast)  AS 'Year',
        MONTH(b.DateOfServiceLast) AS 'Month',
        b.DiagnosisCode,
        SUM(c.Paid) OVER (PARTITION BY
                              YEAR(b.DateOfServiceLast),
                              MONTH(b.DateOfServiceLast),
                              (b.DiagnosisCode)
                         )         AS 'Cost',
        ROW_NUMBER() OVER (PARTITION BY
                               YEAR(b.DateOfServiceLast),
                               MONTH(b.DateOfServiceLast)
                           ORDER BY
                               YEAR(b.DateOfServiceLast),
                               MONTH(b.DateOfServiceLast)
                          )        AS 'Row'
FROM
        MO_CMTExtract.dbo.ProfessionalClaim            a
    LEFT JOIN
        MO_CMTExtract.dbo.ProfessionalClaimDetail      b
            ON a.ProfessionalClaimID = b.ProfessionalClaimID
    LEFT JOIN
        MO_CMTExtract.dbo.ProfessionalClaimDetailMoney c
            ON b.ProfessionalClaimDetailID = c.ProfessionalClaimDetailID)

SELECT TOP 10 WITH TIES *
FROM CTE
ORDER BY ROW_NUMBER() OVER (PARTITION BY YEAR ORDER BY COST DESC)

答案 1 :(得分:0)

您可以按以下方式使用ROW_NUMBER,然后使用行号进行过滤:

WITH cte_base
AS (   SELECT  DISTINCT
               YEAR(b.DateOfServiceLast)  AS 'Year',
               MONTH(b.DateOfServiceLast) AS 'Month',
               b.DiagnosisCode,
               SUM(c.Paid) OVER (PARTITION BY
                                     YEAR(b.DateOfServiceLast),
                                     MONTH(b.DateOfServiceLast),
                                     (b.DiagnosisCode)
                                )         AS 'Cost'
       FROM
               MO_CMTExtract.dbo.ProfessionalClaim            a
           LEFT JOIN
               MO_CMTExtract.dbo.ProfessionalClaimDetail      b
                   ON a.ProfessionalClaimID = b.ProfessionalClaimID
           LEFT JOIN
               MO_CMTExtract.dbo.ProfessionalClaimDetailMoney c
                   ON b.ProfessionalClaimDetailID = c.ProfessionalClaimDetailID),
     cte_rownum
AS (   SELECT
           cte_base.Year,
           cte_base.Month,
           cte_base.Cost,
           cte_base.Row,
           ROW_NUMBER() OVER (PARTITION BY
                                  YEAR(b.DateOfServiceLast)
                              ORDER BY
                                  cte_base.Cost DESC
                             ) AS 'Rownum'
       FROM
           cte_base)
SELECT
    *
FROM
    cte_rownum
WHERE
    cte_rownum.Rownum <= 10
ORDER BY
    cte_rownum.Year,
    cte_rownum.Month,
    cte_rownum.Cost DESC;