2013-07-23 62 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'形成另一个查询是可能的,但是如果您可以在一个查询中做到这一点,为什么还要麻烦呢? –