2016-12-12 4 views
1

私は今日は気分が悪いですが、書きたい質問がありますが、それが私の手の届かないところにあるかもしれないと感じています。このクエリを書くことができますか?私は何が欠けていますか?

私は簡単にするために問題を簡略化しようとします。

は、私は同じクラスを共有するすべての人々のためのすべてのレコード(でグループ化されていない実際のレコード)を取得する必要があり、この

[Table A] 
ID | Class | Name 
0  A  Sarah 
1  B  Tom 
2  C  Bob 
3  A  Jen 
4  A  John 
5  A  Jack 
6  B  Name1 
7  B  Jack 
8  B  Bob 

のようなテーブルを持っていますが、次のような制限付き:

Jen、Jack & Johnが同じクラスを共有しているレコードのみを取得します(他の3つは重複していません)。

SELECT Class, Name, COUNT(*) 
FROM TableA 
GROUP BY Class, Name 
HAVING COUNT(*) = 3 

しかし中:レコードはしたがって、上記の例では、私は

3  A  Jen 
4  A  John 
5  A  Jack 
これまでのところ、私が得ている

になるだろう3.

のセットとして来ることを意味します

これが正しく機能しないことに加えて、私はレコードの名前がJen、Jack、Johnという名前でなければならないと指定することができません。

EDIT: 私は内側のクエリを使用してそれを行うことができたが、それは少しslow..If誰も私に教えてください、より最適な方法を知っている:

SELECT .... 
FROM TableA t1 
join TableA t2 on t1.class = t2.class 
WHERE t1.name = 'Jen' AND t2.name = 'John' 
AND t1.class IN(SELECT class FROM TableA t3 WHERE t3.name = 'Jack'))) 

私はおそらくT3に含まれている可能性が元のクエリですが、私はこの方法を読みやすくする方が好きです。

これが正解ではあるが、私が探していたクエリがこのスタイルを使用していたのかどうかはわからず、同じ方法で単純なものを書こうとした。

+0

要件が明確でない - 明らかになったら、おそらくクエリを書く方が簡単になります。あなたは、実際には、以下の特性を持つすべてのクラスを探していますか?(1)Jen、John、Jackはすべてこのクラスを受けています。 (2)誰もこのクラスを受けていないのですか?もしそうなら、 'select * from tableA from class in(select class from ... where ...)'が正しい方向になければなりません。 – mathguy

+0

@mathguy - 問題ありません - 質問を編集します。 – AngelicCore

+0

編集したフォームでは、もはや3人の学生だけがクラスを受講するように求められます。 (それほど明確ではありませんが、あなたは "それ以上"を削除しました)。実際に、クラスAを取っているSarahの行を追加しましたが、出力には表示されません。どうか明らかにしてください。 – mathguy

答えて

2

他の人が出席していても3人の人がすべて同じクラスを共有しているクラスの後にいる場合は、WHERE句がないことを除いて、あなたが行("the actual records, not grouped by"を)崩壊したくなかったと見て、。

プラスに興味を持っていた名前が、あなたは分析COUNTなく、集計後にしています。

したがって、何を後にしていることのようなものになります。

WITH table_a AS (SELECT 0 ID, 'A' CLASS, 'Sarah' NAME FROM dual UNION ALL 
       SELECT 1 ID, 'B' CLASS, 'Tom' NAME FROM dual UNION ALL 
       SELECT 2 ID, 'C' CLASS, 'Bob' NAME FROM dual UNION ALL 
       SELECT 3 ID, 'A' CLASS, 'Jen' NAME FROM dual UNION ALL 
       SELECT 4 ID, 'A' CLASS, 'John' NAME FROM dual UNION ALL 
       SELECT 5 ID, 'A' CLASS, 'Jack' NAME FROM dual UNION ALL 
       SELECT 6 ID, 'B' CLASS, 'Name1' NAME FROM dual UNION ALL 
       SELECT 7 ID, 'B' CLASS, 'Jack' NAME FROM dual UNION ALL 
       SELECT 8 ID, 'B' CLASS, 'Bob' NAME FROM dual) 
-- End of mimicking your table_a with data in it 
-- See query below: 
SELECT ID, 
     CLASS, 
     NAME 
FROM (SELECT ID, 
       CLASS, 
       NAME, 
       COUNT(NAME) OVER (PARTITION BY CLASS) name_cnt 
     FROM table_a 
     WHERE NAME IN ('Jen', 'Jack', 'John')) 
WHERE name_cnt = 3; 

をあなたは、あなたがしなければならないことを意味し、分析関数は集約関数が行うことと等価HAVING句を持っていないことに注意しましょう外側のクエリでのフィルタリング。あなたのクエリはあなたのものと似ていることが分かりましたか?

+0

私はOPが学生だと思っていますが、まだ分析関数を研究していないかもしれません(つまり、 。 – mathguy

+0

実際に私はソフトウェアエンジニアですが、SQLよりもはるかに多くのコード(とlinq)に頼っている人 - それが結果です:) – AngelicCore

+0

Boneistありがとうございます - 私はあなたのSQLで遊んで、どうやって行ったのか教えてくれます。 – AngelicCore

関連する問題