2009-05-07 10 views
2

クライアント情報をリストするプロジェクトテーブルがあります。次に、私はそのプロジェクト内の仕事のために4つの関連する仕事テーブルを持っています - 屋根裏、サイディング、溝やその他。 4つのテーブルには、ProjectsテーブルにリンクするためのprojectIDフィールドがあり、すべてに 'status'フィールドがあります。プロジェクトには、任意の組み合わせのジョブを含めることができます。関連する複数のテーブルを評価するためのSQLステートメント

すべてのジョブステータスフィールドが「完了」とマークされているプロジェクトのみを選択できます。

これは簡単な方法ですが、私の脳は時にはSQLで過熱することがあります。

+0

あなたはどのデータベース/サーバーを使用していますか? –

+0

私はSQL Serverを使用しています。 –

+0

あなたはたぶん、ぼかし、サイディング、屋根葺きなどを表すジョブタイプのJobItemテーブルを1つだけ持っているでしょう。 – cjk

答えて

3

多分...:

SELECT * FROM Projects 
LEFT JOIN Roofing ON (projectID) 
LEFT JOIN Siding ON (projectID) 
LEFT JOIN Gutters ON (projectID) 
LEFT JOIN Misc ON (projectID) 
WHERE (Roofing.status IS NULL OR Roofing.status="completed") 
AND (Siding.status IS NULL OR Siding.status="completed") 
AND (Gutters.status IS NULL OR Gutters.status="completed") 
AND (Misc.status IS NULL OR Misc.status="completed") 
+0

ステータスフィールドは、デフォルトでは常に「待機」で始まるので、NULLであってはいけません。だから私は文のIS NULL部分が必要ですか? –

2
select p.* 
from project as p 
where not exists (select 1 from roofing where projectId = p.projectId and status <> 'completed') 
    and not exists (select 1 from siding where projectId = p.projectId and status <> 'completed') 
    and not exists (select 1 from gutters where projectId = p.projectId and status <> 'completed') 
    and not exists (select 1 from misc where projectId = p.projectId and status <> 'completed') 
+0

ニースの "否定論理"アプローチ! –

0
SELECT * 
FROM Projects 
    --Step 3: filter the projects by the results from Step2 
WHERE ProjectID not in 
(
    SELECT ProjectID 
    FROM 
    (
    --Step 1: gather all the jobs into one bucket 
    SELECT ProjectID, Status 
    FROM Roofing 
     UNION ALL 
    SELECT ProjectID, Status 
    FROM Siding 
     UNION ALL 
    SELECT ProjectID, Status 
    FROM Gutters 
     UNION ALL 
    SELECT ProjectID, Status 
    FROM Misc 
) as Jobs 
    --Step 2: find incomplete project IDs 
    GROUP BY Jobs.ProjectID 
    HAVING MIN(Jobs.Status) != 'COMPLETED' 
    OR MAX(Jobs.Status) != 'COMPLETED' 
) 
2

アレックスのアプローチは(ない複数のレコードが子テーブルに存在しない場合)あなたに1本のライン上のすべての情報を取得しますが、必要がある場合1つのsepartes行は、すべての文の和集合を試します。それぞれのユニオンで同じ列を使用していることを確認してください。 1つ以上のテーブルに他のテーブルにないデータがある場合は、そのユニオン内のそのカラムの値としてnullを使用します。

SELECT p1.projectid,'roofing' as JobType FROM Projects p1 
JOIN Roofing r ON p1.projectID = r.projectID 
union all 
SELECT p1.projectid,'gutters' as JobType FROM Projects p1 
JOIN gutters g ON p1.projectID = g.projectID 
union all 
SELECT p1.projectid,'siding' as JobType FROM Projects p1 
JOIN Siding s ON p1.projectID = s.projectID 
union all 
SELECT p1.projectid,'misc' as JobType FROM Projects p1 
JOIN Misc m ON p1.projectID = m.projectID 
0

「完了したすべてのジョブ」のための明確なProjectIdsを返し、プロジェクトのテーブルにそれを結合ビューを作成します。そうすれば、「すべてのジョブが完了しました」の条件が変更された場合、ビューを更新するだけで済みます。新しいジョブが追加された場合。ビューのSQL文は、他の応答に示すようにいくつかの方法で構築できます。

関連する問題