按ntile和row_number排序行

时间:2015-01-09 12:32:17

标签: sql sql-server tsql sql-server-2012

我正在尝试构建将返回Crystal Reports报表数据的存储过程。 在CR内部我使用多列布局。

我希望获得3个布局列:

 1    5   8
 2    6   9
 3    7   10
 4

但是因为CR有一些布局问题,所以我这样订购我的表:

 1    2   3
 4    5   6
 7    8   9
10

所以我试图创建一个程序,它将返回我将对数据进行排序的额外列。

所以相反1,2,3,4顺序我需要1,4,7,10,2,5,8,3,6,9 ...

我有数据表:

ID | CASE_ID |  CASE_DATE
--------------------------
 1 |   1     | 2014-02-03
 2 |   1     | 2014-02-04
 3 |   1     | 2014-02-05
 4 |   1     | 2014-02-06
 5 |   1     | 2014-02-07
 6 |   1     | 2014-02-08
 7 |   1     | 2014-02-09
 8 |   1     | 2014-02-10
 9 |   1     | 2014-02-11
10 |   1     | 2014-02-12

我需要存储过程来返回这些数据:

ID | CASE_ID |  CASE_DATE | ORDER
---------------------------------
 1 |   1     | 2014-02-03 |    1
 2 |   1     | 2014-02-04 |    5
 3 |   1     | 2014-02-05 |    8
 4 |   1     | 2014-02-06 |    2
 5 |   1     | 2014-02-07 |    6
 6 |   1     | 2014-02-08 |    9
 7 |   1     | 2014-02-09 |    3
 8 |   1     | 2014-02-10 |    7
 9 |   1     | 2014-02-11 |    10
10 |   1     | 2014-02-12 |    4

以下是sql中包含示例数据和我的代码:http://sqlfiddle.com/#!3/c24c1/1

排序列背后的想法:

  1. 将所有行划分为3组(ntile),从第一组中获取第一项,然后从第二组中获取第一项,从第三组中获取第一项
  2. 修改 这是我的临时解决方案,我希望运行此解决方案可以澄清我在提出这个问题时的想法:

    --DECLARE @NUM INT;
    --SET @NUM=3;
    
    SELECT ID,
           CASE_ID,
           CONVERT(NVARCHAR(10),CASE_DATE,121) AS DATA,
           (ROW1 - 1) * 3/*@NUM*/ + COL AS [ORDER]
    FROM
      ( SELECT CASE_ID,
               ID,
               ROW AS LP,
                      COL,
                      ROW_NUMBER() OVER (PARTITION BY CASE_ID, COL ORDER BY ROW) AS ROW1,
                      CASE_DATE
       FROM
         (SELECT ROW_NUMBER() OVER (PARTITION BY D.CASE_ID ORDER BY D.ID) AS ROW,
                 NTILE(3/*@NUM*/) OVER (PARTITION BY D.CASE_ID ORDER BY D.ID) AS COL,
                 ID,
                 D.CASE_ID,
                 CASE_DATE
          FROM DATA D
          WHERE D.CASE_ID = 1)X )Y
    ORDER BY Y.CASE_ID,
             LP
    

1 个答案:

答案 0 :(得分:0)

修改:看起来您确实需要ORDER列,而不仅仅是按顺序返回列。

SELECT ID,
    CASE_ID,
    DATA,
    ROW_NUMBER() OVER (ORDER BY ROW, N) AS [ORDER]
FROM (
    SELECT ID,
        CASE_ID,
        N,
        ROW_NUMBER() OVER (PARTITION BY CASE_ID, N ORDER BY ID) AS ROW,
        DATA
    FROM (
        SELECT 
            ID, 
            CASE_ID,
            NTILE(3) OVER (PARTITION BY CASE_ID ORDER BY ID) AS N,
            CONVERT(NVARCHAR(10), CASE_DATE,121) AS DATA
        FROM DATA
        WHERE CASE_ID = 1 ) X ) Y
ORDER BY ID;

SQLFiddle