根据SQL Server中的记录计数将记录拆分为2列

时间:2017-08-16 07:36:48

标签: sql sql-server sql-server-2008 tsql stored-procedures

我正在尝试从单个表中选择记录。我有两列显示记录。

我必须根据计数拆分记录。也就是说,我需要将每个部分的记录分成20行。

此外,如果我有超过40条记录,则需要在第1列显示记录。

请参阅随附的屏幕截图:

enter image description here

记录应该是这样的:

enter image description here

我在存储过程中尝试了以下查询,但看起来我错过了一些东西。如果记录数大于40,则不会按预期检索。

任何帮助都会非常感激。

CREATE proc mytest2
AS
    IF OBJECT_ID('tempdb..#test1') IS NOT NULL
       DROP TABLE #test1

    IF OBJECT_ID('tempdb..#test2') IS NOT NULL
       DROP TABLE #test2 

    SELECT 
        ROW_NUMBER() OVER (ORDER BY rno) 'rno',
        Reg, SerialNo  
    INTO 
        #test1 
    FROM
        (SELECT
             ROW_NUMBER() OVER (ORDER BY ID) 'rno',
             Reg, SerialNo  
         FROM
             tRe) AS c
    WHERE
        rno % 20 = 0

    SELECT
        ROW_NUMBER() OVER (ORDER BY rno) 'rno1',            
        Reg AS Reg1, SerialNo AS SerialNo1 
    INTO
        #test2 
    FROM
        (SELECT
             ROW_NUMBER() OVER (ORDER BY ID) 'rno',
             Reg, SerialNo  
         FROM
             tRe) AS c
    WHERE
        rno % 20 <> 1

    SELECT * 
    FROM #test1 a 
    FULL OUTER JOIN #test2 b ON a.rno = b.rno1

     ------


EXEC mytest2

2 个答案:

答案 0 :(得分:1)

将您的居住条件更改为: 对于第一个查询:

 WHERE (rno % 20 > 0 AND (rno / 20) % 2 = 0)  OR     (rno % 20 = 0 AND (rno / 20) % 2 = 1)

第二次查询:

 WHERE (rno % 20 > 0 AND (rno / 20) % 2 = 1)   OR    (rno % 20 = 0 AND (rno / 20) % 2 = 0)

也就是说你的查询将是:

IF OBJECT_ID('tempdb..#test1') IS NOT NULL
    DROP TABLE #test1

IF OBJECT_ID('tempdb..#test2') IS NOT NULL
    DROP TABLE #test2 

SELECT  ROW_NUMBER() OVER ( ORDER BY rno ) 'rno' ,
        Reg ,
        SerialNo
INTO    #test1
FROM    ( SELECT    ROW_NUMBER() OVER ( ORDER BY EmployeeId ) 'rno' ,
                    Reg ,
                    SerialNo
          FROM      tRe
        ) AS c
WHERE   ( rno % 20 > 0
          AND ( rno / 20 ) % 2 = 0
        )
        OR ( rno % 20 = 0
             AND ( rno / 20 ) % 2 = 1
           )

SELECT  ROW_NUMBER() OVER ( ORDER BY rno ) 'rno1' ,
        Reg AS Reg1 ,
        SerialNo AS SerialNo1
INTO    #test2
FROM    ( SELECT    ROW_NUMBER() OVER ( ORDER BY EmployeeId ) 'rno' ,
                    Reg ,
                    SerialNo
          FROM      tRe
        ) AS c
WHERE   ( rno % 20 > 0
          AND ( rno / 20 ) % 2 = 1
        )
        OR ( rno % 20 = 0
             AND ( rno / 20 ) % 2 = 0
           )

SELECT  *
FROM    #test1 a
        FULL OUTER JOIN #test2 b ON a.rno = b.rno1

答案 1 :(得分:0)

这里有一个更简单的代码来实现相同的目标(你不需要使用临时表,你可以创建一个带有行编号功能的CTE,然后再引用它两次):

WITH
    CTE AS (
        SELECT
            Reg, SerialNo, 
            rn = (ROW_NUMBER() OVER (ORDER BY Reg) - 1) / 20 + 1,
            rn2 = (ROW_NUMBER() OVER (ORDER BY Reg)) % 20
        FROM
            [tRe]
    )

SELECT 
    a.Reg, a.SerialNo, b.Reg, b.SerialNo
FROM 
    CTE a
LEFT OUTER JOIN
    CTE b ON a.rn2=b.rn2 AND a.rn=b.rn-1
WHERE
    a.rn % 2 = 1