2016-08-18 159 views
1

我有三個關係爲GradParent(Country)> Parent(State)> Child(People)的表。我試圖通過國家名稱實現查詢以獲取以下情景和訂單的獨特信息。
1.所有人的數據與他們的國家和國家。
2.如果州沒有人員,則州和國家數據。
3.如果沒有國家和/或人民,那麼只是國家數據。與多個外連接的SQL查詢

表: enter image description here

SQL:

SELECT DISTINCT P1.ID as COUNTRY_ID, P1.NAME AS COUNTRY_NAME, P2.ID AS STATE_ID, 
P2.Name AS STATE_NAME , I1.ID AS PEOPLE_ID, I1.NAME AS PEOPLE_NAME 
FROM dbo.Country P1 
    INNER JOIN dbo.State P2 
     ON P2.Country_ID = P1.ID 
     INNER JOIN dbo.People I1 
      ON I1.Country_ID = P1.ID 

    <!-- WHERE P1.Name like 'USA%'--- optional--> 
    ORDER BY P1.NAME 
+1

試圖改變你的'INNER JOIN's爲'LEFT JOIN's – Shnugo

+0

像其他評論說/已經回答,你需要什麼(生產與無狀態的國家行,並沒有爲國家/國家我們會編輯它以反映出來,然後,你的數據模型沒有被標準化(這不好),PEOPLE表只能有state_id;每個國家的國家已經顯示在STATE表中,在PEOPLE中重複這些關係至多是多餘的,最壞的情況是相互矛盾的,我認爲這是某種功課;我不喜歡你的老師,他們用這樣的表教壞習慣 – mathguy

+0

- 你的數據庫產品是什麼?你同時擁有SQL Server和Oracle,這實際上是正確的(只有兩個)約1%的病例。 – mathguy

回答

1

使用LEFT OUTER連接。即使沒有匹配的子記錄,這些也會將信息保留在父表中。

此外,根據您的數據模型,您不應該需要DISTINCT關鍵字。毫無理由地拋出這種做法是不好的做法。

最後,您的加入條件PEOPLE需要限制STATE_ID

SELECT p1.id AS country_id, 
     p1.name AS country_name, 
     p2.id AS state_id, 
     p2.name AS state_name, 
     i1.id AS people_id, 
     i1.name AS people_name 
FROM dbo.country p1 
     LEFT JOIN dbo.state p2 ON p2.country_id = p1.id 
     LEFT JOIN dbo.people i1 ON i1.country_id = p1.id AND i1.state_id = p2.id 
-- WHERE P1.Name like 'USA%'--- optional-- 
ORDER BY p1.name, p2.name, i1.name 
+1

Nitpick ...爲什麼別名'p1'代表'國家','P2'代表'國家','I1'代表'人們'?爲什麼'''''''''國家'''''''國家','P'爲'人'? :-)另外,連接條件'i1.country_id = p1.id'是多餘的 - 一旦狀態在'人'和'狀態'之間正確匹配,並且國家在'國家'和'國家之間正確匹配','人民'和'國家'將自動匹配(或者表中包含內部矛盾 - 可憐的窮人,非正常設計的影響之一)。 – mathguy

+0

他沒有發表餐桌設計。我不想假設state_id是State表中的主鍵,認爲它很可能是。就表格別名而言,我使用了OP使用的內容。 –