Sql 按第2列上的分组排序

Sql 按第2列上的分组排序,sql,sql-server,Sql,Sql Server,我一直试图解决这个问题,但没有成功 这是我的桌子 SN PID ---- --------- 1 NULL 2 1000005 3 NULL 4 1000002 5 1000005 6 NULL 7 1000002 8 NULL 9 1000005 我需要按序列号排序,但当PID不为空时,需要将它们分组在一起。因此,我要寻找的结果是 SN PID ----

我一直试图解决这个问题,但没有成功

这是我的桌子

SN      PID
----    ---------
1       NULL
2       1000005
3       NULL
4       1000002
5       1000005
6       NULL
7       1000002
8       NULL
9       1000005
我需要按序列号排序,但当PID不为空时,需要将它们分组在一起。因此,我要寻找的结果是

SN      PID
----    ---------
1       NULL
2       1000005
5       1000005    -- group together with the previous SAME PID
9       1000005    -- continue to group together
3       NULL       -- continue to the next unused SN (no more PID = 1000005)
4       1000002
7       1000002    -- group together with the previous SAME PID
6       NULL       -- continue to the next unused SN
8       NULL

感谢任何人的建议。谢谢

我将通过使用一个人工列进行排序来解决这个问题,该人工列等于具有相同
PID
的所有行的MIN
SN
,或者等于
PID
为空时的
SN

SELECT *,
 CASE 
   WHEN PID IS NULL THEN SN
   ELSE (SELECT MIN(t2.SN) FROM MyTable t2 WHERE t2.PID=t1.PID)
 END AS sortby
FROM MyTable t1
ORDER BY sortby, SN

如果需要在输出中排除
sortby
,可以将上述内容用作CTE,也可以将大小写表达式直接插入ORDER BY,并将其从选择列表中删除。

我将使用窗口函数:

select sn, pid
from (select t.*,
             dense_rank() over (order by pid desc) as seqnum_pid,
             row_number() over (partition by pid order by sn) as seqnum_null
      from t
     ) t
order by (case when pid is null then seqnum_null else seqnum_pid end),
         (case when pid is null then 1 else 2 end);
他是一把小提琴

或者,您可以按的顺序使用窗口功能:

select sn, pid
from t
order by (case when pid is null then sn else min(sn) over (partition by pid) end)

如果将
MIN
OVER
子句一起使用,则可以将其放在CTE中,并将其放入子查询(以及表的第二次扫描)中。是的,使用相同的基本原则,有几种不同的编写方法。我觉得子查询是最具说明性的例子,尽管不是最有效的。我使用CTE消除了额外的SortBy列。工作起来很有魅力!为什么空值不在一起?