SQL SERVER:每个字段前10行 - 如果少于10行,则显示空行

时间:2015-09-30 15:55:15

标签: sql sql-server

我需要根据SYS_CD值选择TOP 10 ACCT行。因此我写了下面的查询。查询工作正常。

SELECT SYS_CD, ACCT, CNTACCT ,rowid
FROM
  ( SELECT SYS_CD, ACCT, COUNT(ACCT) AS CNTACCT,
           ROW_NUMBER() OVER (PARTITION BY SYS_CD
                              ORDER BY COUNT(ACCT) DESC
                             )
             AS rowid
    FROM [FCIDIAL].[dbo].table1
    WHERE ERR_CD != 'Y'

     GROUP BY SYS_CD, ACCT
  ) tmp
WHERE rowid <= 10
ORDER BY SYS_CD, rowid, ACCT;

提供以下结果

SYS_CD FIN_AAAT    CNTFIN_AAAT rowid
AAA     606000          4        1
AAA     566000          3            2
AAA     503200          1            3
BBB     251260      42433978         1
BBB     400601      41181797         2
BBB     400401      8399908          3
BBB     503200      2087703          4
BBB     604000      40795        5
BBB     130039      4748             6
BBB     252000      655              7
BBB     736000      40               8
BBB     735000      38               9
BBB     734000      36               10
CCC     233210      73611         1
CCC     464250      39397             2
CCC     186020      35231             3
CCC     265155      4949              4

查询结果也正确。

但我的预期输出是,对于SYS_CD,如果rowid小于10,则显示剩余行的空白行。

示例:在上面的“AAA”中只有3个rowid。所以我需要显示7个空白行 'BBB'有10个rowid。所以不需要空行。 'CCC'有4个rowid,所以我需要显示6个空行。

我期待以下输出。

SYS_CD ACCT        CNTACCT        rowid
AAA     606000          4        1
AAA     566000          3            2
AAA     503200          1            3
                    - Blank Row 
                    - Blank Row 
                    - Blank Row 
                    - Blank Row 
                    - Blank Row 
                    - Blank Row 
                    - Blank Row 
                    - Blank Row 
BBB     251260      42433978         1
BBB     400601      41181797         2
BBB     400401      8399908          3
BBB     503200      2087703          4
BBB     604000      40795        5
BBB     130039      4748             6
BBB     252000      655              7
BBB     736000      40               8
BBB     735000      38               9
BBB     734000      36               10
CCC     233210      73611         1
CCC     464250      39397             2
CCC     186020      35231             3
CCC     265155      4949              4
                    - Blank Row 
                    - Blank Row 
                    - Blank Row 
                    - Blank Row 
                    - Blank Row 
                    - Blank Row 
                    - Blank Row 
                    - Blank Row 

我如何才能达到预期效果。

2 个答案:

答案 0 :(得分:3)

您需要获取SYS_CD的所有值,以及1到10之间的数字表:

SELECT  ccd.SYS_CD, n.RowID
FROM    (SELECT DISTINCT SYS_CD FROM [FCIDIAL].[dbo].table1 WHERE ERR_CD != 'Y') AS ccd
        CROSS JOIN (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) AS n (RowID);

完成此操作后,您可以LEFT JOIN返回原始查询,这样您最终会找到NULL缺少的记录:

WITH tmp AS
(   SELECT  SYS_CD, 
            ACCT, 
            COUNT(ACCT) AS CNTACCT,
            ROW_NUMBER() OVER (PARTITION BY SYS_CD ORDER BY COUNT(ACCT) DESC) AS rowid
    FROM    [FCIDIAL].[dbo].table1
    WHERE   ERR_CD != 'Y'
    GROUP BY SYS_CD, ACCT
) 
SELECT  ccd.SYS_CD, tmp.ACCT, tmp.CNTACCT, n.RowID
FROM    (SELECT DISTINCT SYS_CD FROM [FCIDIAL].[dbo].table1 WHERE ERR_CD != 'Y') AS ccd
        CROSS JOIN (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) AS n (RowID)
        LEFT JOIN tmp
            ON tmp.SYS_CD = ccd.SYS_CD
            AND tmp.rowid = n.RowID
ORDER BY ccd.Sys_CD, n.RowID;

答案 1 :(得分:0)

如果您没有现有的计数表,您可以很容易地在运行中生成一个计数表。假设你是在2008 +上,这应该可行。

with MyData as
(
    SELECT SYS_CD
        , ACCT
        , COUNT(ACCT) AS CNTACCT
        , ROW_NUMBER() OVER (PARTITION BY SYS_CD ORDER BY COUNT(ACCT) DESC) AS rowid
    FROM [FCIDIAL].[dbo].table1
    WHERE ERR_CD != 'Y'
    GROUP BY SYS_CD
        , ACCT
)

select *
from (Values(1),(2), (3), (4), (5), (6), (7), (8), (9), (10)) n(x)
left join MyData d on d.rowid = n.x
order by d.SYS_CD, n.x