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
的所有行的MINSN
,或者等于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列。工作起来很有魅力!为什么空值不在一起?