我有一个查询,目前会显示如下数据:
ID | Name | Arrival | Departure
-----------------------------------
1 | John | NULL | 2:30:00
2 | John | NULL | 11:00:00
3 | John | NULL | 14:00:00
4 | John | 10:30:00 | 11:00:00
5 | John | 12:00:00 | 13:00:00
这是我做的时候:order by Name, Arrival, Departure
。
但是,我想要的是以下内容:
NULL
,则应按行排序
出发专栏。 NULL
AND
有多个行具有相同的Departure数据,然后它
应该在之后对具有到达的其他行进行排序
条目。结果:
ID | Name | Arrival | Departure
-----------------------------------
1 | John | NULL | 2:30:00
4 | John | 10:30:00 | 11:00:00
2 | John | NULL | 11:00:00
5 | John | 12:00:00 | 13:00:00
3 | John | NULL | 14:00:00
编辑:对于那些认为这是一个重复问题的人 - 由于第二个条件,原来问题不一样。但是,由于我的数据结构的方式(到达时间总是在出发时间之前),相同的答案是适用的。
编辑2:出发也可以是NULL。当Departure为null时,Arrival条目为非null。如果是这种情况,应该通过抵达订购。如果两行都有相同的Arrival条目,那么NULL应该是非空的。请注意,这与NULL Arrival条目(上面的条件2)相反,其中NULL在非null之后。
答案 0 :(得分:3)
尝试
DECLARE @tbl TABLE(ID INT,Name VARCHAR(100),Arrival TIME,Departure TIME);
INSERT INTO @tbl VALUES
(1,'John',NULL,'2:30:00')
,(2,'John',NULL,'11:00:00')
,(3,'John',NULL,'14:00:00')
,(4,'John','10:30:00','11:00:00')
,(5,'John','12:00:00','13:00:00');
SELECT * FROM @tbl
ORDER BY Name,CASE WHEN Arrival IS NULL THEN Departure ELSE Arrival END
结果
1 John NULL 02:30:00.0000000
4 John 10:30:00.0000000 11:00:00.0000000
2 John NULL 11:00:00.0000000
5 John 12:00:00.0000000 13:00:00.0000000
3 John NULL 14:00:00.0000000
您可能会考虑ISNULL()
,但您应该阅读“sargable”,特别是如果您处理许多行和索引...
答案 1 :(得分:1)
没有条件表达式和函数的简单ORDER
怎么样。
如果您想首先按Departure
订购,那么请按顺序排序。
如果您希望在Arrival
旁边订购,但最后想要NULL
,请使用DESC
。
即使Arrival
与Departure
相同,这也会正常工作,例如,如果第{4}行Arrival
为11:00:00
而不是10:30:00
。
我要感谢@Shnugo为脚本提供测试数据。
DECLARE @tbl TABLE(ID INT,Name VARCHAR(100),Arrival TIME,Departure TIME);
INSERT INTO @tbl VALUES
(1,'John',NULL,'2:30:00')
,(2,'John',NULL,'11:00:00')
,(3,'John',NULL,'14:00:00')
,(4,'John','10:30:00','11:00:00')
,(5,'John','12:00:00','13:00:00');
SELECT *
FROM @tbl
ORDER BY
Name
,Departure
,Arrival DESC;
<强>结果强>
+----+------+------------------+------------------+
| ID | Name | Arrival | Departure |
+----+------+------------------+------------------+
| 1 | John | NULL | 02:30:00.0000000 |
| 4 | John | 10:30:00.0000000 | 11:00:00.0000000 |
| 2 | John | NULL | 11:00:00.0000000 |
| 5 | John | 12:00:00.0000000 | 13:00:00.0000000 |
| 3 | John | NULL | 14:00:00.0000000 |
+----+------+------------------+------------------+
虽然......目前尚不清楚是否可能有多行非空Arrival
且完全相同Departure
...您有什么要求排序在这种情况下?
答案 2 :(得分:0)
您可以按照我认为的顺序执行案例陈述。
ISNULL将是我首选的方式,因为它专门用于处理空值而且它更小。
ORDER BY Name, ISNULL(Arival, Departure)
答案 3 :(得分:0)
为了避免在WHERE
子句中使用条件,您可以使用计算列来保留排序条件。此外,使用TIME类型进行到达和离开更有效(空间,比较等):
create table Data
(
ID INT NOT NULL,
Name VARCHAR(100) NOT NULL,
Arrival TIME NULL,
Departure TIME NULL,
ActualTime AS ISNULL(Arrival, Departure) PERSISTED
)
GO
INSERT INTO Data (ID, Name, Arrival, Departure)
VALUES
(1,'John',NULL,'2:30:00')
,(2,'John',NULL,'11:00:00')
,(3,'John',NULL,'14:00:00')
,(4,'John','10:30:00','11:00:00')
,(5,'John','12:00:00','13:00:00');
GO
select * from Data
order by ActualTime
根据其他查询,您还可以使用ActualTime
作为关键字索引。
答案 4 :(得分:0)
要获得null,我认为你可以添加
ORDER BY Name
, ISNULL(Arival, dateadd(ss, 1, Departure))
, Departure
但是如果你到达下一个出发时出现空值,那么你将得到一些可能不理想的结果 你需要准确说明你想要如何处理
如果你有什么
6 | John | 12:30:00 | 11:00:00
你真的想要吗
5 | John | 12:00:00 | 13:00:00
首先对出发进行排序会更容易
declare @bigdate datetime = cast('2099-01-01' as datetime);
ORDER BY Name
, Departure
, ISNULL(Arival, @bigdate);