5

mysqlの1つのクエリでこれを行う最良の方法は何ですか?

SELECT * FROM products WHERE language = 1

結果がなければ

SELECT * FROM products WHERE language = 2 AND country = 1

結果がなければ

SELECT * FROM products WHERE language = 2 AND country = 2
4

5 に答える 5

7

機能するように編集しましたが、エレガントではなくなりました。


オリジナル(最後なしで存在しない)には欠陥がありました。

これは私が思っていたほど賢くないことがわかりました。以下のコメントを参照してください。最初と 3 番目のクエリがデータを返す場合、失敗します。ユニオンが 1 つだけの場合は機能しますが、2 つ以上の場合は機能しません。


mysql では非常に簡単です。

select SQL_CALC_FOUND_ROWS * from products where language = 1
union
SELECT * FROM products WHERE language = 2 AND country = 1 and found_rows()=0
union
SELECT * FROM products WHERE language = 2 AND country = 2 and found_rows()=0 
AND not exists(select * from products where language = 1)

ここで found_rows() と SQL_CALC_FOUND_ROWS の説明を参照してください: http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_found-rows

于 2013-04-24T14:07:23.860 に答える
2

次のようなものを使用できます: (コメントに基づいて EXISTS および LIMIT を使用するように編集されています)。

(
SELECT * FROM products WHERE language = 1
)
UNION
(
SELECT * FROM products WHERE language = 2 AND country = 1
AND NOT EXISTS(SELECT count(*) FROM products WHERE language = 1 limit 1)
)
UNION
(
SELECT * FROM products WHERE language = 2 AND country = 2 
AND NOT EXISTS(SELECT count(*) FROM products WHERE language = 2 AND country = 1 limit 1)
AND NOT EXISTS(SELECT count(*) FROM products WHERE language = 1 limit 1)
)

ネストされたクエリと count(*) を使用して、前のクエリが NULL であることを確認します。

于 2013-04-24T14:08:00.103 に答える
1

試す:

select p.* 
from (select min(language) minlang, min(country) minctry 
      from products where language = 1 or
                          (language = 2 and country in (1,2)) ) c
join products p 
on p.language = c.minlang and (c.minlang=1 or p.country=c.minctry)
于 2013-04-24T14:08:05.993 に答える
1

MySQL には、これを一度に実行できる機能がありません
。例:DENSE_RANKウィンドウ関数、またはTOP..WITH TIES

したがって、一時テーブルまたは IF ステートメント (とにかく MySQL でストアド プロシージャを必要とする) を使用せずに、クライアントでこれをフィルター処理して、優先度の最も低い値にします。つまり、値が変更されるまで行を消費します

SELECT *, 1 AS priority FROM products WHERE language = 1
UNION ALL
SELECT *, 2 AS priority FROM products WHERE language = 2 AND country = 1
UNION ALL
SELECT *, 3 AS priority FROM products WHERE language = 2 AND country = 2
ORDER BY priority;

これにより、理想的ではありませんが、MySQL サーバーへのラウンドトリップが削除されます。また、EXISTS 句で以前の SELECT を再評価することも回避します。

于 2013-04-24T14:03:57.307 に答える