2013-07-23 174 views
2

我是SQL開發新手。所以我想從SO獲得一些幫助。SQL查詢獲取數據

我有三個表:學生student_addressesstudent_phones

其架構大致如下:

student 
------- 
student_id (Primary Key) 
student_name 
father_name 
mother_name 

student_addresses 
----------------- 
student_address_id (Primary Key) 
student_id (Foreign Key) 
address 
zip_code 

student_phones 
-------------- 
student_phone_id (Primary Key) 
student_id (Foreign Key) 
phone_type 
phone_number 

兩個student_addressesstudent_phones是的has_many關係。所以我想從學生選擇所有字段特定student_id數據但僅從student_addresses匹配的次數(總)和student_phonesstudent_id數據。我如何獲得?

我已經試過此查詢,但它返回一個錯誤:

SELECT students.student_id,student_name,father_name,mother_name, 
     COUNT(student_addresses.student_id) AS total_addresses,  
     COUNT(student_phones.student_id) AS total_phones 
FROM students,student_phones,student_addresses 
WHERE students.student_id = student_phones.student_id AND 
     students.student_id = student_addresses.student_id AND 
     students.student_id = 7; 

PS:目前我使用這個在PostgreSQL上。不過,我也想在MySQL上工作。那麼這是否意味着我需要有兩個不同的查詢? AFAIK,爲此目的,只有一個查詢可以同時工作(因爲MySQL和PostgreSQL遵循相同的SQL實現,就這個查詢要求而言)。

我想知道,如果我可以做到這一點,而不使用GROUP BY。因爲,假設學生表有更多的字段,比如說12,那麼我將不得不將所有的字段名稱都放到SELECT中,以及放在GROUP BY(AFAIK)中,這似乎有點不雅觀。

+1

做student_addresses和student_phones有他們自己的主鍵?如果是這樣,他們是什麼?另外,你使用PostgreSQL或MySQL? –

+0

@MarkBannister,我沒有注意到它有2個不同的數據庫。我真的認爲它是MySQL。很高興你指出這一點。 –

+0

@Mark:我編輯了這個問題。謝謝。 –

回答

1

這應該在MySQL和PostgreSQL工作:

SELECT s.student_id, 
     max(s.student_name) student_name, 
     max(s.father_name) father_name, 
     max(s.mother_name) mother_name, 
     COUNT(distinct a.student_address_id) total_addresses,  
     COUNT(distinct p.student_phone_id) total_phones 
FROM students s 
LEFT JOIN student_phones p ON s.student_id = p.student_id 
LEFT JOIN student_addresses a ON s.student_id = a.student_id 
WHERE s.student_id = 7 
GROUP BY s.student_id 
+2

爲什麼這裏需要max()函數? –

+0

@ M-D:因爲這是一個分組查詢 - select語句中的所有列都必須包含在分組標準中,或者被彙總。我更喜歡使用聚合函數(如'max'),因爲對於分組而言,不需要**的字段,因爲它更清楚「真實」分組是什麼。 –

+0

完美!謝謝。 –

1

只需添加GROUP BY

SELECT students.student_id,student_name,father_name,mother_name, 
     COUNT(student_addresses.student_id) AS total_addresses,  
     COUNT(student_phones.student_id) AS total_phones 
FROM students,student_phones,student_addresses 
WHERE students.student_id = student_phones.student_id AND 
     students.student_id = student_addresses.student_id AND 
     students.student_id = 7 
GROUP BY students.student_id,student_name,father_name,mother_name; 

但如果它發生學生ID爲7沒有地址或沒有電話號碼,它不會返回任何結果。即使在這種情況下返回的東西,嘗試使用LEFT JOIN S:

SELECT students.student_id,student_name,father_name,mother_name, 
     COUNT(student_addresses.student_id) AS total_addresses,  
     COUNT(student_phones.student_id) AS total_phones 
FROM students 
LEFT JOIN student_phones ON students.student_id = student_phones.student_id 
LEFT JOIN student_addresses ON students.student_id = student_addresses.student_id 
WHERE students.student_id = 7 
GROUP BY students.student_id,student_name,father_name,mother_name; 
1

你忘了包括GROUP BY

SELECT students.student_id,student_name,father_name,mother_name, 
      COUNT(student_addresses.student_id) AS total_addresses,  
      COUNT(student_phones.student_id) AS total_phones 
    FROM students,student_phones,student_addresses 
    WHERE students.student_id = student_phones.student_id AND 
      students.student_id = student_addresses.student_id AND 
      students.student_id = 7 
    GROUP BY BY students.student_id,student_name,father_name,mother_name; 
+1

我想知道,如果我可以做到這一點,而不使用GROUP BY。因爲,假設學生表有更多的字段,比如說12,那麼我將不得不把所有的字段名稱都放到SELECT以及GROUP BY中,這似乎有點不雅觀。我不正確嗎? –

+0

只需創建一個'VIEW'並用'INNER JOIN'形成另一個查詢是可能的,但是如果您可以在一個查詢中做到這一點,爲什麼還要麻煩呢? –