【问题标题】:Order rows by ntile and row_number按 ntile 和 row_number 对行进行排序
【发布时间】:2015-01-09 12:32:16
【问题描述】:

我正在尝试构建将为 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,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 fiddle 示例数据和我的代码:http://sqlfiddle.com/#!3/c24c1/1

排序列背后的想法:

  1. 将所有行分成 3 组(ntile),从第一组中取出第一项,然后从第二组中取出第一项,从第三组中取出第一项

编辑: 这是我的临时解决方案,我希望运行它可以澄清我在问这个问题时的想法:

--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

【问题讨论】:

  • 订单列背后的逻辑是什么??
  • @Ganesh_Devlekar Crystal Reports 正在创建列然后向下(如顶部的第二个表所示)如果我想正确显示数据,我需要以某种方式对其进行排序。想法是将所有行分成3列,然后在它们放置第二行之后取第一行,依此类推。抱歉,我的母语不是英语。
  • 我不明白。为什么第二行的顺序是“5”?据我所知,您需要第二行第一列中的值。
  • @GordonLinoff 很抱歉给您带来了麻烦。我在我的问题中固定了表格
  • "...因为 CR 有一些布局问题..." 这些布局问题是与 CR 忽略您的设计有关,还是与您不知道有关 如何让 CR 做蛇形列?因为CR can do that.

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


【解决方案1】:

编辑:看起来您实际上想要 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

【讨论】:

  • 我已经添加了临时解决方案,也许这会澄清我的问题。
猜你喜欢
  • 2019-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-08
  • 2011-08-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多