2016-05-21 10 views
1

私はSQLiteテーブル(メッセージ用)を持っています。この表には、注文の列が2つあります(createdsent)。 sentフィールド(降下)でソートされた結果を取得する必要がありますが、0がある場合はcreatedフィールド(降下)もあります。SQLite - COALESCEが結果の順序を破る

私はSQL関数COALESCEを使用していますが、結果の順序が間違っています。私は、順序が正しい、式=0を除去しようとしたが、その要求は」doesnの

SELECT * FROM messages ORDER BY COALESCE(sent,created)=0 DESC 
┌─────────────┬──────────┬────────────┬────────────┐ 
│ external_id │ body │ created │ sent │ 
├─────────────┼──────────┼────────────┼────────────┤ 
│  ...  │ Te │ 1463783516 │ 1463662248 │ 
├─────────────┼──────────┼────────────┼────────────┤ 
│  ...  │ huyak │ 1463783516 │ 1463662248 │ 
├─────────────┼──────────┼────────────┼────────────┤ 
│  ...  │ tete │ 1463783516 │ 1463662248 │ 
├─────────────┼──────────┼────────────┼────────────┤ 
│  ...  │ qw │ 1463793500 │ 1463793493 │ <- 
└─────────────┴──────────┴────────────┴────────────┘ 

正常な結果(COALESCEなし):

SELECT * FROM messages ORDER BY sent DESC 
┌─────────────┬──────────┬────────────┬────────────┐ 
│ external_id │ body │ created │ sent │ 
├─────────────┼──────────┼────────────┼────────────┤ 
│  ...  │ qw │ 1463793500 │ 1463793493 │ <- 
├─────────────┼──────────┼────────────┼────────────┤ 
│  ...  │ huyak │ 1463783516 │ 1463662248 │ 
├─────────────┼──────────┼────────────┼────────────┤ 
│  ...  │ tete │ 1463783516 │ 1463662248 │ 
├─────────────┼──────────┼────────────┼────────────┤ 
│  ...  │ Te │ 1463783516 │ 1463662248 │ 
└─────────────┴──────────┴────────────┴────────────┘ 

誤った結果(COALESCE付き)正しく動作した場合sent = 0

SELECT * FROM messages ORDER BY COALESCE(sent,created) DESC 
┌─────────────┬──────────┬────────────┬────────────┐ 
│ external_id │ body │ created │ sent │ 
├─────────────┼──────────┼────────────┼────────────┤ 
│  ...  │ qw │ 1463793500 │ 1463793493 │ <- 
├─────────────┼──────────┼────────────┼────────────┤ 
│  ...  │ huyak │ 1463783516 │ 1463662248 │ 
├─────────────┼──────────┼────────────┼────────────┤ 
│  ...  │ tete │ 1463783516 │ 1463662248 │ 
├─────────────┼──────────┼────────────┼────────────┤ 
│  ...  │ Te │ 1463783516 │ 1463662248 │ 
└─────────────┴──────────┴────────────┴────────────┘ 
but 
┌─────────────┬──────────┬────────────┬────────────┐ 
│ external_id │ body │ created │ sent │ 
├─────────────┼──────────┼────────────┼────────────┤ 
│  ...  │ Te │ 1463783516 │ 1463662248 │ 
├─────────────┼──────────┼────────────┼────────────┤ 
│  ...  │ huyak │ 1463783516 │ 1463662248 │ 
├─────────────┼──────────┼────────────┼────────────┤ 
│  ...  │ tete │ 1463783516 │ 1463662248 │ 
├─────────────┼──────────┼────────────┼────────────┤ 
│  ...  │ qw │ 1463793500 │  0  │ <- 
└─────────────┴──────────┴────────────┴────────────┘ 

なぜそれが起こっているのか、それを修正する方法を知っていますか?

+0

私はSOキーワード検索として「huyak」を使用して何かを見つけた私の驚きを想像してみてください。なぜお願いしますか:) – alecxe

+0

@alecxe easter eggs) – Dmitry

答えて

2

COALESCEはNULLを処理しますが、ここでは役に立ちません。常にsentが返されます。その結果をゼロと比較すると、sentがゼロかどうかに基づいてのみソートされます。あなたは、あなたが比較せずにCOALESCEを使用することができます何のタイムスタンプが存在しないNULLを持っていた場合CASE

... ORDER BY CASE sent WHEN 0 THEN created ELSE sent END DESC; 

を使用する必要があります。

+0

おかげで、あなたの質問はうまくいきます。パフォーマンスについて - どのオプションが良いですか: 'COALSCE'(私のコードを変更して、代わりに' null'を0にする)か 'CASE'ですか? – Dmitry

+0

@ドミトリーほとんどの場合、COALESCEは優れていますが、主にデータの整合性に関するものです。 NULLは「値なし」であり、可能な場合はそのように使用する必要があります。より効果的なものを見るには、ケースをベンチマークする必要があります。 –

+0

わかりました、多くのありがとうございます。 – Dmitry

0

COALESCEはゼロではなくNULLを処理します。

あなたはnullif() functionでNULLにゼロ値に変換することができます:

SELECT * FROM messages ORDER BY COALESCE(NULLIF(sent,0),created) DESC; 
関連する問題