4

そのタイトルは残忍ですが、他になんと言っていいのかわかりません。

サイト全体でユーザー設定を保存する user_id に関連付けられたキー値テーブルがあります。ユーザーがログインして設定を更新していない場合は、キーを要求するたびに (「FAVORITE_COLOR」など) キーが null になるため、デフォルト ユーザーに関連付けたデフォルト設定を取得する必要があります。ユーザー ID = 0。

user_id = 0 の結果をクエリの最後に UNION するという行に沿って考えていましたが、それは重複につながるだけです。それが可能かどうかはわかりませんが、次のようなことを言えたらいいのにと思います。

SELECT val FROM k_v WHERE user_id = 123 AND k = 'FAVORITE_COLOR'
UNION IF val IS NULL
SELECT val FROM k_v WHERE user_id = 0 AND k = 'FAVORITE_COLOR';

これを行う良い方法はありますか?

編集:これに関するすべての助けに感謝します。ユースケースがこの質問である単一の値のみを取得する場合、デュアルからの NVL はまさにあなたが望むものですが、同じクエリで複数のペアを返すことを計画している場合は、他のいくつかを見てください実際には実装にとってより意味があるかもしれないので、答えてください。

以下の ZeissS の提案は単純で、まだ 1 つのクエリであり、複数の k,v ペアで動作し、クライアント側で重複フィルタリングの可能性がある場合でも問題はありません。

4

4 に答える 4

6

これを使って、

select
  nvl(
    (SELECT val FROM k_v WHERE user_id = 123 AND k = 'FAVORITE_COLOR'),
    (SELECT val FROM k_v WHERE user_id = 0 AND k = 'FAVORITE_COLOR')
  ) val 
from dual
;

Oracleのドキュメントから、

NVL(expr1、expr2):NVLを使用すると、クエリの結果でnull(空白として返される)を文字列に置き換えることができます。expr1がnullの場合、NVLはexpr2を返します。expr1がnullでない場合、NVLはexpr1を返します。

于 2010-07-21T17:02:52.120 に答える
2

おそらく、参加を終了してから、最も適切なものを選択することができます。

SELECT
  NVL(best.val, fallback.val) as val
FROM
  (SELECT val FROM k_v WHERE user_id = 0 AND k = 'FAVORITE_COLOR') as fallback
  left outer join (SELECT val FROM k_v WHERE user_id = 123 AND k = 'FAVORITE_COLOR') as best on 1 = 1

oracle構文はわかりませんが、ある種の相互結合の代わりに「1=1の左外側」結合を使用することもできます。

于 2010-07-21T17:05:04.490 に答える
2

私はこのようなことをします:

SELECT k_v.v FROM k_v WHERE userid IN (:userid, 0) ORDER BY userid DESC

返された最初の行のみを使用します。

于 2010-07-21T17:35:55.057 に答える
0
SELECT nvl(k.k,kd.k) as k, 
       nvl(k.val, kd.val) as val 
FROM (select * from k_v where user_id = 0) kd 
     full outer join 
     (select * from k_v where user_id = 123) k 
     on kd.k = k.k 
WHERE 'FAVORITE_COLOR' in (k.k,kd.k)

デフォルトがない場合、またはユーザー固有の結果がない場合の両方で結果が保証されるため、完全な外部結合を実行することをお勧めします。デフォルトが欠落している可能性がない場合は、クエリを少し簡略化できます。

SELECT nvl(k_v.k,kd.k) as k, 
       nvl(k_v.val, kd.val) as val 
FROM k_v kd 
     left outer join k_v 
     on kd.k = k_v.k 
        and k_v.user_id = 123
WHERE kd.k = 'FAVORITE_COLOR'
  and kd.user_id = 0
于 2010-07-21T17:03:18.170 に答える