想象一下,我有一个包含以下内容的数据集:
Date Id
-------------- ----
11/1/2017 null
11/4/2017 3
11/5/2017 null
11/12/2017 10
null 1
null 2
null 7
null 8
null 9
我想要排序的行,以便两列都在增加。
使用天真ORDER BY Date, ID
不会这样做:
有一个顺序可以满足我所需的排序顺序的结果:
当然,这不是一个独特的订单:
Date Id
-------------- ---------------
null 1
11/1/2017 null
null 2
11/4/2017 3
null 7
null 8
null 9
11/5/2017 null
11/12/2017 10
我知道我可以在客户端完成此任务。在函数式函数编程语言中:使用stable sorting algorithm:
稳定排序是保留输入原始顺序的排序 set,其中比较算法不区分两者 或更多项目。
考虑一种排序算法,按 rank 对卡进行排序,但不是 适合。稳定的排序将保证卡的原始顺序 保持相同等级;不稳定的排序不会。
不幸的是我有
单调增加行以尽可能按时间顺序排序。显然我更喜欢在服务器上执行此操作 - 这非常适合处理大量数据。
如何在SQL Server中执行稳定排序?
CREATE TABLE #SortDemo (Date datetime NULL, Id int NULL)
INSERT INTO #SortDemo (Date, Id)
VALUES
('20171101', null),
('20171104', 3),
('20171105', null),
('20171112', 10),
(null, 1),
(null, 2),
(null, 7),
(null, 8),
(null, 9)
SELECT * FROM #SortDemo
ORDER BY Date, Id
答案 0 :(得分:0)
这是一个可以解决的问题。 You不必举起手来说计算机不能用来解决问题。
从数据开始,添加新的代理“Rank”列。
Date Id Rank
-------------- ---- ----
null 7 null
null 1 null
null 9 null
null 2 null
null 8 null
11/1/2017 null null
11/4/2017 3 null
11/5/2017 null null
11/12/2017 10 null
11/13/2017 null null
然后将Rank
种到Id
:
UPDATE SortDemo SET Rank = Id
WHERE Id IS NOT NULL
Date Id Rank
-------------- ---- ----
null 7 7
null 1 1
null 9 9
null 2 2
null 8 8
11/1/2017 null null
11/4/2017 3 3
11/5/2017 null null
11/12/2017 10 10
11/13/2017 null null
然后对于带有日期的剩余项目项目,我们需要将其分配给“next”排名:
Date Id Rank
-------------- ---- ----
null 7 7
null 1 1
null 9 9
null 2 2
null 8 8
11/1/2017 null null <-- 3
11/4/2017 3 3
11/5/2017 null null <-- 10
11/12/2017 10 10
11/13/2017 null null <-- ?
与
UPDATE SortDemo SET Rank = (
SELECT MIN(Rank) FROM SortDemo s2
WHERE s2.Date >= SortDemo.Date)
WHERE SortDemo.Date IS NOT NULL
Date Id Rank
-------------- ---- ----
null 7 7
null 1 1
null 9 9
null 2 2
null 8 8
11/1/2017 null 3 <--
11/4/2017 3 3
11/5/2017 null 10 <--
11/12/2017 10 10
11/13/2017 null null <-- ?
还有一个边缘情况,在我们之后没有项目“;我们可以通过向后退到前一个最高级别来修复:
UPDATE SortDemo SET Rank = (
SELECT MAX(Rank) FROM SortDemo s2
WHERE s2.Date <= SortDemo.Date)
WHERE SortDemo.Date IS NOT NULL
Date Id Rank
-------------- ---- ----
null 7 7
null 1 1
null 9 9
null 2 2
null 8 8
11/1/2017 null 3
11/4/2017 3 3
11/5/2017 null 10
11/12/2017 10 10
11/13/2017 null 10 <--10
我们现在可以按代理Rank
排序,并按Date
排序来打破关系:
SELECT * FROM SortDemo
ORDER BY Rank, Date
Date Id Rank
-------------- ---- ----
null 1 1
null 2 2
11/1/2017 null 3
11/4/2017 3 3
null 7 7
null 8 8
null 9 9
11/5/2017 null 10
11/12/2017 10 10
11/13/2017 null 10
解决方案完成。 Sql Fiddle
答案是在第三方托管,直到星期一,所以我可以给人们机会赢得解决一个独特问题的声誉。