2011-10-18 5 views
1

次のスキーマのAとBのSQLクエリを書く方法に関するヒントを得ることができませんでした。すべての従業員 'for all'を含むSQLクエリ

彼のすべての部門の プログラムに参加する従業員のB.名

が参加するプログラムの

Programme (Pid:int, Department:string...) 
Employee (Eid:int, Department:string..) 
Participation (Pid:int, Eid:int, ..) 

A.名前。

ガイドラインは参考になります。

+1

[この記事を参照](http://www.simple-talk.com/sql/t-sql-programming/divided-we-stand-the-sql-of-relational -division /) –

+0

このようなクエリの最適化に関する最近の質問(PostgresとMySQL)。これを行うにはさまざまな方法があります:http://stackoverflow.com/questions/7364969/how-to-filter-sql-results-in-a-has-many-through-relation/ –

答えて

1

はこれらを試していないが、これは私が考えてしまうものです:

SELECT pg.Name 
FROM Participation AS p INNER JOIN Programme AS pg ON p.Pid = pg.Pid 
GROUP BY p.Pid 
HAVING COUNT(*) = (SELECT COUNT(*) FROM Employeee) 



SELECT e.Name 
FROM Participation AS p INNER JOIN Employee AS e ON p.Eid = e.Eid 
         INNER JOIN Programme AS pg ON pg.Pid = p.Pid 
WHERE pg.Department = e.Department 
GROUP BY p.Eid, e.Department, e.Name 
HAVING COUNT(*) = (SELECT COUNT(*) 
        FROM Programme AS pg2 
        WHERE pg2.Department = e.Department) 
+0

グループはありません属性によって、2番目のクエリの選択ですか? – Nemo

+0

グッドキャッチは、グループに追加したばかりの名前で、結果には影響しません。 –

1

使用WHERE NOT EXISTSと外側がすべての普遍的なプログラムについて

をジョイン:

SELECT * FROM Programme 
WHERE NOT EXISTS (SELECT * FROM 
        (Participation NATURAL JOIN Programme) LEFT JOIN Employee 
         USING (Eid,Department) 
        WHERE Employee.Eid IS NULL) 

これがあるべき説明が簡単 - 従業員が参加していないすべてのプログラムを選択

すべてenthusiatic従業員のための

:再び

SELECT * FROM Employee 
WHERE NOT EXISTS (SELECT * FROM 
        Employee LEFT JOIN Participation 
         USING (Eid,department) 
        WHERE Participation.Eid IS NULL) 

は - その従業員が参加していないされているのと同じ部署にはプログラムが存在しないすべてのemployyesを選択します。あなたがすべてで正式なロジックに精通している場合


これは見覚えがあるかもしれ - ユニバーサル定量化は、一般的に定義されて否定実存資格の面で

3

必要なリレーショナル演算子は、一般に"the supplier who supplies all parts"として知られ、divisionです。

これは、exact divisionであるかどうか、または余りのある除算と空の除数の扱い方です。

UPDATE:明確にするために、SQLには明示的な除算演算子またはキーワード**がありません。ただし、他の演算子を使用してSQLでリレーショナル除算を行うことができます。私は、「宿題」タグのために実例を投稿することを控えます。しかし、私が普段使っているのは、「演算子を持つ除算」の例に似ています(例:this link)。

@Dylan Smithは「Celko's division」としてよく知られているもので、@ tobyodaviesの答えは「Date's Division」として知られているもののバリエーションを使用しています(Dateは外部結合を使用しませんが、代わりにNOT EXISTS )。しかし、おそらく彼らは本当にこれらの確立されたアプローチを再考しました。 ;)

**同じことが多くの他の関係演算子にも当てはまります。 SQLには半差分演算子はありませんが、他のSQL演算子を使用して実行できます。 NOT IN,NOT EXISTS,EXCEPTなど

+0

残念ながらSQLには除算がありません。 – tobyodavies

+0

@tobyodavies:除算演算子やキーワードは欠落していますが、除算は他の演算子で実現できます。私は、「宿題」タグのために実例を投稿することを控えます。しかし、私が通常使っているのは、[このリンク](http://www.simple-talk.com/sql/t-sql-programming/divided-we-stand-the)の "Set Operatorsを持つ部門"の例に似ています-sql-of-relational-division /)を使用します。 p.s.同じことが他の多くの関係演算子にも当てはまります。 SQLには半差分演算子はありませんが、他のSQL演算子を使用して実行できます。 – onedaywhen

+0

@tobyodavies:あなたの答えは、「Date's division」と呼ばれるもののバリエーションですが、Dateはアウターを使用しません2番目の 'NOT EXISTS'が参加します。 – onedaywhen

関連する問題