复杂的SQL查询:正确连接四个不同的表

时间:2011-03-06 00:29:35

标签: mysql select join

我有4个表:users,userpreference,userinfo,useredu

最后三个表使用“id”作为引用表'users'的外键:

要制定的查询:

我需要找到“去MSU的所有单身女性中的顶级音乐”

注意到MSU也可能是'明尼苏达州立大学'

到目前为止我有这个查询,但它没有产生正确的结果?

select userpreference.preferencevalue as 'Music', COUNT(*) as 'SingleFemaleCount'from users, userpreference, userinformation
where users.Id = userinformation.Id
and users.Id = userpreference.Id
and userpreference.Id = userinformation.Id
and users.Gender = 'female'
and userinformation.informationvalue = 'single'
and usereducation.school like 'msu%' OR like 'minnesota state%'
and userpreference.preferencetype = 'music' GROUP BY preferencevalue ORDER BY      COUNT(distinct users.Id) DESC limit 10

3 个答案:

答案 0 :(得分:1)

可能就像你在where子句中需要一些括号一样简单:

(usereducation.school like 'msu%' OR like 'minnesota state%')

否则,OR的优先级低于相邻的AND。

编辑:2011-03-06

下面,我对代码进行了格式化,使其更易于阅读,并将userinformationusereducation检查移至exists()子句中。我这样做的原因是,如果用户有超过1个符合您条件的userinformationusereductionat行,则会影响count()聚合。

select
    userpreference.preferencevalue as 'Music',
    COUNT(*) as 'SingleFemaleCount'

from users, userpreference
where users.Gender = 'female'
  and userpreference.Id = users.Id
  and userpreference.preferencetype = 'music'

  and exists
    (select *
    from userinformation
    where userinformation.Id = users.Id
      and userinformation.informationvalue = 'single')

  and exists
    (select *
    from usereducation
    where usereducation.Id = users.Id
      and (usereducation.school like 'msu%' OR like 'minnesota state%'))

GROUP BY userpreference.preferencevalue
ORDER BY COUNT(*) DESC limit 10

要检查的另一件事是(usereducation.school like 'msu%' OR like 'minnesota state%')确实找到了所有MSU记录。如果结果集不是太大,则运行select distinct school from usereducation进行检查,确保您获得所有记录。

最后,我更喜欢使用连接语法,如下所示:

select
    userpreference.preferencevalue as 'Music',
    COUNT(*) as 'SingleFemaleCount'

from users
inner join userpreference on userpreference.Id = users.Id
where users.Gender = 'female'
  and userpreference.preferencetype = 'music'

  and exists
    (select *
    from userinformation
    where userinformation.Id = users.Id
      and userinformation.informationvalue = 'single')

  and exists
    (select *
    from usereducation
    where usereducation.Id = users.Id
      and (usereducation.school like 'msu%' OR like 'minnesota state%'))

GROUP BY userpreference.preferencevalue
ORDER BY COUNT(*) DESC limit 10

我意识到我完全改变了你的查询,但是这是功课,对吧:)。

答案 1 :(得分:0)

达娜是对的。您还需要在from子句中添加usereducation:

from users, userpreference, userinformation, usereducation

并将其加入用户。

答案 2 :(得分:0)

好的,一旦你在“FROM”中添加了usereducation并且它已经加入了users表(你不需要加入其他表,但如果你愿意,可以使用它)。试试下面的内容。

在查询中,如果要在WHERE子句中查找等于一个值或另一个值的列,则需要列出两次列:

AND (usereducation.school LIKE 'msu%' OR usereducation.school LIKE 'minnesota state%')