MySQL查询以查找由第二个表中的另一个值连接的列中最受欢迎的值

时间:2012-11-18 04:36:52

标签: php mysql sql join

我有两张桌子:

  • 用户:user_id,user_zip
  • 设置:user_id,pref_ex_loc

我需要根据特定的user_zip从设置表中找到最受欢迎的'pref_ex_loc',它将被指定为变量$ userzip。

这是我现在的查询,显然它不起作用。

$popularexloc = "SELECT pref_ex_loc, user_id COUNT(pref_ex_loc) AS countloc 
       FROM settings FULL OUTER JOIN users ON settings.user_id = users.user_id 
       WHERE users.user_zip='$userzip' 
       GROUP BY settings.pref_ex_loc 
       ORDER BY countloc LIMIT 1";

$popexloc = mysql_query($popularexloc) or die('SQL Error :: '.mysql_error());
$exlocrow = mysql_fetch_array($popexloc); 
$mostpopexloc=$exlocrow[0];
echo '<option value="'.$mostpopexloc.'">'.$mostpopexloc.'</option>';

我在这里做错了什么?我也没有收到任何错误。

4 个答案:

答案 0 :(得分:1)

嗯,首先,你在COUNT()之前缺少一个逗号:

SELECT pref_ex_loc, user_id COUNT(...

您的选择列表中的每个字段之间应该有一个逗号:

SELECT pref_ex_loc, user_id, COUNT(...

我建议使用COUNT(*)代替COUNT(pref_ex_loc)。在这种情况下,要么应该给出正确答案,要么在MySQL COUNT(*)中通常表现得稍好一些。

您正在使用外部联接,但是在WHERE子句中,您正在测试users的其中一列,因此它实际上不再是外部联接。在此查询中,我认为您只需要一个INNER JOIN,除非您需要处理没有任何用户引用您的pref_ex_loc值的任何的可能性。阅读A Visual Explanation of SQL Joins

另外,MySQL does not support FULL OUTER JOIN

当select-list中的user_id既不在GROUP BY子句中也不在聚合函数中时,它是一个不明确的字段,从组中的任意一行获取其值。您应该从选择列表中删除user_id

按countloc DESC排序,以获得最大值。

所以这就是我认为更好的查询:

SELECT pref_ex_loc, COUNT(*) AS countloc 
FROM settings INNER JOIN users ON settings.user_id = users.user_id 
WHERE users.user_zip='$userzip' GROUP BY settings.pref_ex_loc 
ORDER BY countloc DESC LIMIT 1

答案 1 :(得分:1)

尝试一下:

select s.pref_ex_loc from settings s
join users u on (u.user_id = s.user_id)
where user_zip = $userzip
group by s.pref_ex_loc
order by count(*) desc
limit 1

正如您所说,这将根据特定的user_zip从设置表中为您提供“最受欢迎的单个'pref_ex_loc'”

答案 2 :(得分:1)

这将允许列表中显示最高pref_ex_loc的值(重复最常用的)。

它没有使用LIMIT,因为LIMIT会强制显示最大行数。现在,问题是,如果有两行或更多行与最受欢迎的pref_ex_loc绑定怎么办?

SELECT  b.pref_ex_loc
FROM    users a
        INNER JOIN settings b
            ON a.user_ID = b.user_ID
WHERE   a.user_zip = 1  -- change the value here
GROUP BY    b.pref_ex_loc
HAVING COUNT(*) =
(
  SELECT MAX(totalCount)
  FROM
  (
    SELECT  b.pref_ex_loc, COUNT(*) totalCount
    FROM    users a
            INNER JOIN settings b
                ON a.user_ID = b.user_ID
    WHERE   a.user_zip = 1  -- change the value here
    GROUP BY    b.pref_ex_loc
  ) s
)

答案 3 :(得分:0)

尝试使用此查询:

SELECT user_id, COUNT(pref_ex_loc) AS countloc
FROM users LEFT JOIN settings ON users.user_id = settings.user_id
WHERE users.user_zip='$userzip' GROUP BY user_id ORDER BY countloc LIMIT 1