3

あるデータベースに、別のデータベースにリストされていないユーザーのリストが必要ですnew_user_id。両方のデータベースに112,815人の一致するユーザーがいます。user_idすべてのクエリテーブルのキーです。


クエリ#1は機能し、new_user_Idとして参照されていない111,327人のユーザーを取得します。ただし、同じデータを2回クエリする必要があります。

-- 111,327 GSU users are NOT listed as a CSS new user 
--   1,488 GSU users ARE listed as a new user in CSS
--
select count(gup.user_id)
from   gsu.user_profile gup
  join (select cud.user_id, cud.new_user_id, cud.user_type_code
        from   css.user_desc cud) cudsubq
    on gup.user_id = cudsubq.user_id
where  gup.user_id not in (select cud.new_user_id 
                           from   css.user_desc cud
                           where  cud.new_user_id is not null);


クエリ#2は完璧です...そして私はそれが構文的に受け入れられていることに実際に驚いています。しかし、それは私に意味のない結果を与えます。

-- This gives me 1,505 users... I've checked, and they are not
-- referenced as new_user_ids in CSS, but I don't know why the ones 
-- that were excluded were excluded.
--
-- Where are the missing 109,822, and whatexcluded them?
-- 
select count(gup.user_id)
from   gsu.user_profile gup
  join (select cud.user_id, cud.new_user_id, cud.user_type_code
        from   css.user_desc cud) cudsubq
    on gup.user_id = cudsubq.user_id
where  gup.user_id not in (cudsubq.new_user_id);


2番目のクエリのwhere句は正確には何をしているのでしょうか。また、結果から109,822レコードが除外されているのはなぜですか。


上記のクエリは、私が本当に求めているものを単純化したものです。上記のクエリを実行する他の/より良い方法があります...それらは私に問題を与えているクエリの部分の単なる代表です。

4

4 に答える 4

4

これを読んでください:http://asktom.oracle.com/pls/asktom/f?p = 100:11:0 :: NO :: P11_QUESTION_ID:442029737684

私が理解していることですが、両方のテーブルがで結合されていてもcudsubq.new_user_id可能であるため、サブセットにが含まれている場合、演算子を使用して結果を取得することはできません。記事の例を考えてみましょう。NULLuser_idNOT INNULL

select * from dual where dummy not in ( NULL )

これはレコードを返しません。NOT EXISTS演算子または別の種類の結合を使用してみてください。ここに良い情報源があります:http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html

そして、必要なのは4番目の例です。

SELECT COUNT(descr.user_id)
FROM 
    user_profile prof
    LEFT OUTER JOIN user_desc descr
        ON prof.user_id = descr.user_id 
WHERE descr.new_user_id IS NULL
    OR descr.new_user_id != prof.user_id
于 2012-10-29T18:06:31.167 に答える
1

2番目のクエリは意味的に異なります。この場合

where  gup.user_id not in (cudsubq.new_user_id)

cudsubq.new_user_idサブクエリとしてではなく、式( doc:IN condition )として扱われるため、句全体は基本的に次のようになります。

where  gup.user_id != cudsubq.new_user_id

したがって、最初のクエリでは、文字通り「CSSにエントリがあり、GUP.IDがCSSのANY NOTNULLNEW_IDと一致しないGUPのすべてのユーザーを表示する」と尋ねています。

ただし、2番目のクエリは「CSSにもエントリがあり、GUP.IDがRESPECTIVE NULLABLE(句なし、覚えていますか?)CSS.NEW_ID値と等しくないGUPのすべてのユーザーを表示するですis not null

また、nullを使用(not) inした(または等式/不等式)チェックは実際には機能しません。

12:07:54 SYSTEM@oars_sandbox> select * from dual where 1 not in (null, 2, 3, 4);

no rows selected                                                   

Elapsed: 00:00:00.00          

これはあなたがあなたの行を失うところです。where cudsubq.new_user_id is null一致しないユーザーがnullのnew_user_idを持っていると仮定して、おそらく2番目のクエリのwhere句をとして書き直します 。

于 2012-10-30T04:10:29.640 に答える
0

2番目の選択では、現在の参加レコードでgup.user_idとcud.new_user_idを比較します。クエリを書き直して同じ結果を得ることができます

select count(gup.user_id)
from   gsu.user_profile gup
  join (select cud.user_id, cud.new_user_id, cud.user_type_code
        from   css.user_desc cud) cudsubq
    on gup.user_id = cudsubq.user_id
where  gup.user_id != cud.new_user_id or cud.new_user_id is null;

あるデータベースのユーザーのリストを別のデータベースのユーザーのリストと比較するとおっしゃいました。したがって、データを2回クエリする必要があり、同じデータをクエリすることはありません。たぶん、「マイナス」演算子を使用して「in」の使用を避けることができます

select count(gup.user_id)
from   gsu.user_profile gup
  join (select cud.user_id from css.user_desc cud
        minus
        select cud.new_user_id from css.user_desc cud) cudsubq
    on gup.user_id = cudsubq.user_id;
于 2012-10-24T04:32:31.560 に答える
0

あなたはテーブルのどれとも一致しないテーブルからのを欲しいですよnew_user_idね?左参加の仕事のように聞こえます:gupnew_user_idcud

SELECT count(gup.user_id)
    FROM gsu.user_profile gup LEFT JOIN css.user_desc cud
        ON gup.user_id = cud.new_user_id
    WHERE cud.new_user_id is NULL

結合は、のすべての行を保持し、可能gupであればそれらを一致させますnew_user_id。WHERE条件は、に一致する行がない行のみを保持しcudます。

(これをすでに知っていて、not inクエリの動作にのみ関心がある場合は、お詫びします)

于 2012-10-29T21:47:52.533 に答える