8

入力パラメーターに基づいて結果セットを生成する検索クエリがあり、結果は価格、期間などのさまざまなパラメーターに基づいて (ASC/DESC) 並べ替えることができます (ページネーションが設定されており、10 レコードの制限があります)。

id渡された場合、対応するレコードを特定の結果セットの上部に固定する必要があります。

次のようなパッケージ テーブルがあるとします。

Package
 - id
 - name
 - mPrice
 - vPrice
 - duration

// Searching pkg based on Price (in DESC order) where name = Thailand
sqlQuery = 
"SELECT p.id, p.name, p.mPrice, p.vPrice FROM package p 
WHERE p.name = LOWER('Thailand') 
ORDER BY (p.mPrice + p.vPrice) DESC 
LIMIT 10"

完全な結果セットが ID 1 から 20 の 20 レコードであると仮定しましょう。ID 14 のレコードを常に一番上に返す必要があります。次のクエリを思いつきましたが、これは機能しません。

sqlQuery = 
"SELECT p.id, p.name, p.mPrice, p.vPrice FROM package p 
WHERE p.name = LOWER('Thailand') or p.id = 14
ORDER BY CASE 
WHEN p.id=14 then 0 
else (p.mPrice + p.vPrice) 
end DESC 
LIMIT 10"

これが機能しない理由についての私の推測: order by 句の後、結果セットは降順でソートされ、10 レコードで切り捨てられます。id=14 のレコードは、この切り捨てられたセットの一部ではない可能性があります。これは正しいです ?

id=14 のレコードを一番上に固定するにはどうすればよいですか?

4

3 に答える 3

17
ORDER BY (p.id=14) DESC, (p.mPrice=p.vPrice) DESC

p.id=141条件が true の場合は戻ります。0それ以外の場合は、降順で並べ替えると目的の行が一番上に表示されます。

比較から数値を返すことは MySQL の機能であり、標準 SQL では次のように記述します。

ORDER BY CASE WHEN (p.id=14) THEN 0 ELSE 1 END,
         CASE WHEN (p.mPrice=p.vPrice) THEN 0 ELSE 1 END

これは よりも読みやすく、UNIONパフォーマンスが向上する可能性があります。

于 2012-08-06T07:14:48.393 に答える
3

ユニオンを使用して、パッケージを常に一番上に置きます。

SELECT id, name, mPrice, vPrice FROM package WHERE id = 14
UNION
SELECT p.id, p.name, p.mPrice, p.vPrice FROM package p 
WHERE p.name = LOWER('Thailand') or p.id = 14
ORDER BY (p.mPrice = p.vPrice) DESC
LIMIT 9
于 2012-08-06T06:59:48.683 に答える
1

これを試して:

order by 
 case when p.id=14 then then (select MAX(mPrice)+1 from package ) else
(p.mPrice = p.vPrice)  end desc
LIMIT 10

(select MAX(p.mPrice)+1 from package )の代わりに、 常に最大値になる定数値を与えることができます。

 order by 
 case when p.id=14 then then 1000000 else
(p.mPrice = p.vPrice)  end desc
LIMIT 10

どちらがより効率的でしょう

于 2012-08-06T07:03:58.470 に答える