2016-11-15 64 views
1

我已盡全力去解決這個問題,希望這裏有人能幫忙。

我給出的數據庫模式如下:SQL:返回兩個特定學生都參加的所有班級的列表

客戶:ID名姓出生日期

導師:身份證名姓

FitnessClass:標識類名成本InstructorId

認購:CustomerId ClassId StartDate

隨着問題的存在:

檢索所有類的列表(Id和類名),這兩個李四和約翰·斯諾已訂閱(即李四和約翰·斯諾一直在同一個健身班) 。

我嘗試只生產了,要麼是,不僅兩者都是在類的所有類

我嘗試:

SELECT fitnessclass.id, fitnessclass.classname 
FROM fitnessclass 
LEFT JOIN subscription ON fitnessclass.Id = subscription.ClassID 
LEFT JOIN customer ON subscription.CustomerID = customer.ID 
WHERE customer.ID IS NOT NULL 
AND customer.FirstName IN ("Joe", "Bloggs") 
+0

請閱讀[問]和[mcve] s。 – philipxy

+0

你究竟在哪裏試過?因爲'Bloggs'不是第一個名字。 – philipxy

+0

最初是'John'而不是'Bloggs',只是一個抄錄錯誤 – alancussen

回答

1

我們希望從DISTINCTc.ClassIdc.ClassName值其中:

class c.Id is named c.ClassName and costs c.Cost and is taught by c.InstructorId 
AND customer c1.ID is named c1.FirstName c1.LastName and was born on c1.DateOfBirth 
AND customer c2.ID is named c2.FirstName c2.LastName and was born on c2.DateOfBirth 
AND c1.ID <> c2.ID 
AND customer s1.CustomerId subscribed to s1.ClassId starting on s1.StartDate 
AND customer s2.CustomerId subscribed to s2.ClassId starting on s2.StartDate 
AND c1.ID = s1.CustomerId AND c2.ID = s2.CustomerId 
AND c1.FirstName = 'Joe' AND c1.LastName = 'Bloggs' 
AND c2.FirstName = 'John' AND c2.LastName = 'Snow' 
AND s1.ClassId = c.ClassId AND s2.ClassId = c.ClassId 

觀察到沒有重複的別名表保持S(一組)行,使一個真正的語句從報表模板(謂語)由數據庫設計與它的基表相關:

-- class c.Id is named c.ClassName and costs c.Cost and is taught by c.instructorId 
FitnessClass c 

-- cx.ID is named cx.FirstName cx.LastName and was born on cx.DateOfBirth 
Customer cx 

-- customer sx.CustomerId subscribed to class sx.ClassId starting on sx.StartDate 
Subscription sx 

觀察還,如果表達L持有行滿足templateL和表達R保持行滿足templateR然後

  • L JOIN R保持滿足templateL AND templateR
  • R WHERE condition擁有滿足templateR AND condition
  • templateR ON condition行持有滿足templateR AND condition

行因此,我們要從中選擇行是:

FROM Class c 
JOIN Customer c1 JOIN Customer c2 
ON c1.ID <> c2.ID 
JOIN Subscription s1 JOIN Subscription s2 
WHERE 
AND c1.ID = s1.CustomerId AND c2.ID = s2.CustomerId 
AND c1.FirstName = 'Joe' AND c1.LastName = 'Bloggs' 
AND c2.FirstName = 'John' AND c2.LastName = 'Snow' 
AND s1.ClassId = c.ClassId AND s2.ClassId = c.ClassId 

條件可以在相與任何順序只要每個只使用前面的JOIN或JOIN ON中的列。所以如果你認爲它更好,你可以按照其他順序重新排列這些。 (例如,本地化某些列名稱的使用。)(但您通過ON(或「,」不合適)必須組織的參數是specious。)

DISTINCT從FROM等生成的表中刪除非SELECTED列後刪除重複行。這樣做的結果是保留了滿足其模板的行的集合。 DISTINCT並不總是必要的。但你仍然需要不同的行。一般來說,你必須認爲關於你是否可以避免DISTINCT。有時你不能。有時候,你可以推斷你下一步做什麼與重複表格給出相同的答案,不管是否有重複。很少,要求的結果被允許有或應該有重複。但是,當通過簡單的關係模板表達式對應推理時,您無法進一步使用該結果。 (練習:查看是否有選擇的FROM等表返回正確的classid &的className值而不DISTINCT。)

(爲什麼你認爲LEFT JOIN爲宜目前還不清楚它返回什麼JOIN做,但。與無匹配的左錶行擴展NULL)。

+0

感謝您的幫助,作品像一個魅力,這裏有很多信息,我之前並不知道,所以我很欣賞輔導。通過創建c1和c2(客戶的兩個不同版本(?)),只需簡單地澄清一下,它本身就是一種DISTINCT嗎? – alancussen

+0

我不知道什麼「通過創建c1和c2(客戶的兩個不同版本(?)),這是否表現爲DISTINCT本身」的意思。請儘量表達清楚。我編輯的答案涉及DISTINCT的功能,但我不知道這是否對您有幫助。如果你想要一個關於c1.ID&c2.ID的模板,說明他們識別同一個客戶,那麼這就是c1.ID = c2.ID.嘿!我們在規範中發現了一個錯誤。因爲我們想要c1.ID <> c2.ID! PS該模板並沒有討論c1和c2,因爲我們所擁有的只是從c1粘貼一行,從c2粘貼一行,等等。c1.ID等是它的列。 – philipxy

+0

PS另請參閱我對[此](http://stackoverflow.com/q/35032696/3404097)和[this](http://stackoverflow.com/a/33952141/3404097)的回答。 – philipxy

相關問題