2016-09-08 6 views
1

目的:日付Xにロールまたは特定のロールの除外によってログインした人の数を戻します。Oracle SQL:1つの表から数を選択し、別の表からサブクエリを使用して選択範囲を絞り込みます。

私はこれまで、さまざまな方法でこれをやってきました。通常、私が望むものを選択し、アプリケーション言語(PHPなど)を使用して結果セットをループし、2番目のテーブルを照会します。私はこれを行うより効率的な、おそらく純粋なSQLの方法を探しています。

LoginTable 
+--------------------+ 
| userName loginDate | 
+--------------------+ 
| jason 08/15/16  | 
| jason 09/01/16  | 
| john 08/15/16  | 
| john 09/04/16  | 
| cindy 08/15/16  | 
+--------------------+ 
RoleTable 
+--------------------+ 
| userName role| 
+--------------------+ 
| jason admin  | 
| jason student  | 
| jason employee  | 
| john employee  | 
| john admin   | 
| cindy student  | 
| cindy hr   | 
| cindy finance  | 
+--------------------+ 

これを行うための純粋なOracle SQLの方法はありますか?それ以上の後処理は必要ありませんか?

たとえば、次のような質問があります。 08/15/16にログインし、従業員の役割は持っていたが、学生の役割は持っていないユーザー。

答えはjohnです。

loginDate = 08/15/16とLoginTable.userName中(ROLETABLE役割=従業員と役割<>学生からユーザー名を選択します)

はもちろんのこと、クエリが動作しないでしょうLoginTable からユーザー名の選択に。

これを行うための純粋なSQLの方法はありますか、ループ/後処理またはおそらく一時テーブルに戻す必要がありますか?

これらのテーブルには何百万もの行があるので、効率を求めています。

+0

編集、右の表を取得しようとしています。 – JasonW

+1

質問を変更したため、自分の回答が正しく表示されませんでした。あなたはそうしてはいけません。 –

答えて

2

アップデート:ここで

はあなたが決定するためにRoleTableのユーザー上の条件付き集約を使用することができます

もともと(QV以下)頼まれたものと実質的に異なる更新質問への答えでありますどのユーザーにemployeeロールがありましたが、studentロールはありませんでした。その後、さらに08/15/16にログインしているユーザーにこれを制限することができます

SELECT t1.userName 
FROM RoleTable t1 
INNER JOIN LoginTable t2 
    ON t1.userName = t2.userName 
WHERE t1.loginDate = TO_DATE('08/15/16', 'DD/MM/YY') 
GROUP BY t1.userName 
HAVING SUM(CASE WHEN t1.role = 'employee' THEN 1 ELSE 0 END) > 0 AND 
     SUM(CASE WHEN t1.role = 'student' THEN 1 ELSE 0 END) = 0 

注:質問は、私が最初にこの答えを与えたとき以来、実質的に変更されました。元の質問は、特定の日付に記録された生徒の数を各役割ごとに示したものです。

SELECT t1.role, 
     SUM(CASE WHEN t2.userName IS NOT NULL THEN 1 ELSE 0 END) AS peopleCount 
FROM RoleTable t1 
LEFT JOIN LoginTable t2 
    ON t1.userName = t2.userName 
WHERE t1.loginDate = '08/15/16' 
GROUP BY t1.role 
+0

彼は指定された役割を持つ、人の名前を望んでいます。 –

+0

@sql_dummy彼は約1時間前に質問を変更しました。 –

1
SELECT DISTINCT userName 
    FROM LoginTable 
WHERE loginDate = TO_DATE('08/15/16', 'DD/MM/YY') 
    -- include 
    AND userName IN (SELECT userName FROM RoleTable WHERE role = 'employee') 
    -- exclude 
    AND userName NOT IN (SELECT userName FROM RoleTable WHERE role = 'student') 
関連する問題