我正在尝试按照关联表中的顺序对查询结果进行排序。我有三张桌子:
restaurant_user_view
包含用户每次浏览餐厅时的一行。在简化版本中,这些表具有以下结构:
restaurants:
| id | name |
|----|------|
| 1 | Restaurant A|
| 2 | Restaurant B|
| 3 | Restaurant C|
| 4 | Restaurant D|
users:
| id | name |
|----|------|
| 1 | User A|
restaurant_user_view:
| id | user_id | restaurant_id | Timestamp |
|----|---------|---------------|-----------|
| 1 | 1 | 1 | xxxxx |
| 2 | 1 | 3 | xxxxx |
| 3 | 1 | 4 | xxxxx |
| 4 | 1 | 3 | xxxxx |
| 5 | 1 | 2 | xxxxx |
| 6 | 1 | 3 | xxxxx |
| 7 | 1 | 1 | xxxxx |
| 8 | 1 | 1 | xxxxx |
在语义层面,我希望访问最后 3 家餐厅,因此预期输出为: Restaurant A, C, B with the restaurant_id
in restaurant_user_view
table: 1, 3, 2. restaurant_user_view
id
是:8、6、5。
我写了这个查询:
SELECT restaurants.*, restaurant_user_view.timestamp
FROM restaurants
LEFT JOIN restaurant_user_view ON restaurants.id = restaurant_user_view.restaurant_id
WHERE restaurant_user_view.user_id = 1
GROUP BY restaurants.id
ORDER BY restaurant_user_view.timestamp DESC
但是我得到这个输出:restaurant_user_view.restaurant_id
: 2, 4, 3,因为这些是 group by
语句之后最后访问的餐馆。
我没有在网上找到任何解决方案,据我了解问题在于mysql如何处理group by。有什么解决办法吗?
答案 0 :(得分:1)
您可以在派生表中进行聚合以获得每个餐厅的最大时间戳(即最年轻的访问)。加入外部查询并使用 ORDER BY
和 LIMIT
仅获取最年轻的三个访问。
SELECT r.*,
x.timestamp
FROM (SELECT ru.restaurant_id,
max(ru.timestamp) timestamp
FROM restaurant_user_view ru
WHERE ru.user_id = 1
GROUP BY ru.restaurant_id) x
INNER JOIN restaurants r
ON r.id = x.restaurant_id
ORDER BY x.timestamp DESC
LIMIT 3;
注意:除了不能解决您的问题,您的查询格式错误。所选列列表中有一些列既不在 GROUP BY
子句中,也不在聚合函数的参数中。遗憾的是,旧 MySQL 版本或配置不当的实例会接受此类错误查询。但结果可能突然很有趣。
另请注意:时间戳不应是 integer
。 MySQL 中有 datetime
和 timestamp
数据类型。与 integer
不同,它们允许对它们进行日期/时间算术。