0

我有两张桌子:

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

我需要根据特定的 user_zip 从设置表中找到最流行的“pref_ex_loc”,该 user_zip 将指定为变量 $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

4 回答 4

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 值的可能性。阅读SQL 连接的可视化解释

此外,MySQL不支持 FULL OUTER JOIN

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
于 2012-11-18T04:41:19.563 回答
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
)
于 2012-11-18T07:20:11.463 回答
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'”

于 2012-11-18T04:55:06.410 回答
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
于 2012-11-18T04:48:30.590 回答