2016-04-07 20 views
3

私は現在、このようなデータが表示されますクエリを持っている:私はときSQL ServerでNULL結果の順序が異なっていますか?

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ある

  1. 場合、その行は 出発欄で注文する必要があります。
  2. 到着エントリはNULLと 同じ出発データを持つ複数の行がある場合には、それは は到着 エントリを持って後に他の行を注文する必要があります。

結果:

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ではありません。この場合、到着順に発注する必要があります。 2つの行の両方に同じ到着エントリがある場合、NULLはNULL以外である必要があります。これは、NULLの到着エントリ(上記の条件2)の反対であることに注意してください。ここで、NULLはNULL以外の後です。

+0

[条件付き列の値に応じてORDER BYの可能な複製](http://stackoverflow.com/questions/7464434/conditional-order-by-depending-on-column-values) –

+0

第2のルールは多少不明です私。行4の到着が11:00:00になると、到着がnullで出発時刻が11:00:00の行の前に常にあるはずですか? –

+0

@JoachimIsaksson同じ出発点の値を持つ行と、nullを持つエントリの両方を意味します。到着値は、null以外の到着値を持つ行の下にある必要があります。私が言及した理由は、通常はNULLが非NULL値の前に順序付けされるためです。上記の意図した結果では、行4は、null以外のArrival値を持つため、行2の上にあります。 – painiyff

答えて

3

あなたは多くの行とインデックスを扱う場合は特に、あなたがおよそISNULL()と思うかもしれないが、あなたは「検索引数」について読んでください...

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 

でそれを試してみてください

+0

こんにちは!コメントなしで投票してはいけません... – Shnugo

+0

この回答は重複していませんか? http://stackoverflow.com/a/7464492/1507566 –

+0

OPが望んでいたことを達成するには、さまざまな方法がありませんので、別の人が同じ結論に至ったのは驚きではありません。 – dazedandconfused

0

ケースステートメントは、私が信じるorder by節で行うことができます。

ISNULLは、特にヌルで動作するように構築されているため、私の好みの方法です。

ORDER BY Name, ISNULL(Arival, Departure) 
+0

いいえ、[こちら](http://stackoverflow.com/questions/799584/what-makes-a-sql-statement-sargable)と[this](http://stackoverflow.com/questions/5024090/)をお読みください。 sargable-queries-using-isnull-in-tsql)、Btw:私はダウン投票者ではありません... – Shnugo

+0

真。あなたの方がより完全な答えです。 – Jrud

+0

だから、それはsargableではありません。できます。 +1私はそのテーブルの行がたくさんあるとは思わない。 – Paparazzi

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 

他のクエリに基づいて、あなたはまた、キーとしてを使用してインデックスを持つことができます。

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); 
1

最初の出発時にどのように条件式や機能のないシンプルなORDERについて。

Departureで注文したい場合は、最初にそれを注文してください。 Arrivalで注文したいが、最後にNULLが必要な場合は、DESCを使用してください。

これはArrival行4 11:00:00代わりに10:30:00た場合Arrivalは、例えば、Departureと同じであっても正しく動作します。

スクリプトにテストデータを提供してくれて、@ 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 | 
+----+------+------------------+------------------+ 

けれども... null以外Arrivalで複数の行を持っているとDepartureまったく同じことが可能であるかどうかは明らかではない...何発注この場合、あなたは好きですか?

+0

nullでない 'Arrival'と同じ' Departure'を持つ行が2つ以上あってはなりません。しかし、私がOPで言及しなかったことの1つは、「Departure」もヌルになることができるということです。それらがnullの場合、それぞれの「Arrival」はnullではありません。そのような場合は、「到着」によって注文する必要があります。 – painiyff

+0

@painiyff、この場合、 'ORDER BY'に' CASE'や 'ISNULL'や' COALESCE'という式を使う必要があります。 –