SQL ORDER BY-将具有相同值的列分组

Lor*_*orz 5 sql t-sql sql-server sql-order-by

我很难用语言表达我想要的东西(这个标题是我能带给我的最好的东西),使用模式更容易,但是我将首先尝试说明自己。

我想使用以下规则通过查询进行排序:

  1. 通过“组”列对查询进行分组。
  2. 将每个组的“主要”放在其组的顶部。
  3. 如果行的名称与主名称相同,则将其放在主名称之后。
  4. 将其余行按其名称放置

点1、2和4无关紧要。一个简单的ORDER BY技巧。但是我从未见过关于第3点的查询。

我已经阅读了一些有关RANK()ROW_NUMBER()函数的信息,并对其进行了尝试,但是我还没有创建想要的输出。我开始质疑是否有可能这样做。

无论如何,这里有一部分SQL可以对其进行测试。任何帮助表示赞赏。如果您可以找到更好的术语来描述这一点,请随时进行更正。

CREATE TABLE #TEMP
(
    COL_GROUP INT,
    COL_PRIMARY BIT,
    COL_NAME VARCHAR(3)
)

INSERT INTO 
    #TEMP 
VALUES
    (1,1,'AAA'),
    (2,0,'BBB'),
    (2,1,'BBB'),
    (1,0,'BBB'),
    (1,0,'AAA'),
    (2,0,'AAA')

SELECT
     *
FROM 
    #TEMP
ORDER BY 
    COL_GROUP, 
    COL_PRIMARY DESC, 
    COL_NAME

DROP TABLE #TEMP
Run Code Online (Sandbox Code Playgroud)

这给出了以下输出:

COL_GROUP   COL_PRIMARY   COL_NAME
=========   ===========   ========
1           1             AAA  
1           0             AAA
1           0             BBB
2           1             BBB
2           0             AAA
2           0             BBB
Run Code Online (Sandbox Code Playgroud)

我想要的是此输出:

COL_GROUP   COL_PRIMARY   COL_NAME
=========   ===========   ========
1           1             AAA  
1           0             AAA
1           0             BBB
2           1             BBB
2           0             BBB       -- The ones with the same name as the primary first
2           0             AAA
Run Code Online (Sandbox Code Playgroud)

Dhr*_*shi 2

根据评论解决方案

您可以进行自连接并测试名称是否等于主名称,如果是,则分配例如 1 else 0 的值,然后在名称列之前按顺序使用该列。

SELECT
     T1.*
FROM 
    #TEMP T1 JOIN #TEMP T2 
    ON T1.COL_GROUP=T2.COL_GROUP AND T2.COL_PRIMARY=1
ORDER BY 
    T1.COL_GROUP, 
    T1.COL_PRIMARY DESC,
    CASE WHEN T1.COL_NAME=T2.COL_NAME THEN 1 ELSE 0 END DESC,
    T1.COL_NAME
Run Code Online (Sandbox Code Playgroud)

See demo here