以下是我的表格结构:
-- users
+----+--------+
| id | name |
+----+--------+
| 1 | Jack |
| 2 | Peter |
| 3 | Ali |
+----+--------+
-- reputations
+----+-------------+---------+-------+------------+------------+
| id | post_id | user_id | score | reputation | date_time |
+----+-------------+---------+-------+------------+------------+ -- Suppose:
| 1 | 1 | 1 | 1 | 5 | 1500489844 | -- out of last week
| 2 | 4 | 3 | -1 | -2 | 1500499815 | -- out of last week
| 3 | 2 | 3 | 1 | 5 | 1500584821 |
| 4 | 3 | 1 | 1 | 5 | 1501389166 |
| 5 | 2 | 4 | 1 | 5 | 1501399142 |
| 6 | 2 | 1 | -1 | -2 | 1501399142 |
| 7 | 4 | 1 | 0 | 15 | 1501481186 |
+----+-------------+---------+-------+------------+------------+
-- Note: the last row came from an accepted-answer, that's why its score is 0
-- post_tag
+---------+--------+
| post_id | tag_id |
+---------+--------+
| 1 | 2 |
| 1 | 4 |
| 2 | 2 |
| 3 | 1 |
| 3 | 4 |
| 4 | 3 |
+---------+--------+
-- tags
+----+--------+
| id | name |
+----+--------+
| 1 | php |
| 2 | html |
| 3 | css |
| 4 | mysql |
+----+--------+
现在我想获得上周声明,分数,前两个标签的用户列表。我怎么能这样做?
注1: " top tow标签" 表示用户在其中获得更多回购的两个标签。
注2:每个问题至少有1个标记。
这是预期输出:
+----+--------+-------+------------+----------+
| id | name | score | reputation | tags |
+----+--------+-------+------------+----------+
| 1 | Jack | 0 | 18 | css,php |
| 3 | Ali | 1 | 5 | html |
| 2 | Peter | 0 | 0 | NULL |
+----+--------+-------+------------+----------+
-- Note: It's ordered by reputation, score columns
以下是我尝试过的内容:
SELECT u.*,
sum(r.score) as score,
sum(r.reputation) as reputation
/* WS_CONCAT(',', t.name) as tags */
FROM users u
LEFT JOIN reputation r ON r.user_id = u.id
/* I need more joins to get tags, I don't know how exactly */
WHERE r.date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 1 WEEK)
GROUP BY u.id
ORDER BY reputation, score
如您所见,我的查询缺少最后一列(标记)。老实说,我不知道如何管理这样的事情。你知道吗?
答案 0 :(得分:-2)
您是否尝试过使用子查询?类似的东西:
SELECT u.id,u.name,
sum(r.score) as score,
sum(r.reputation) as reputation,
(SELECT group_concat(t.name) FROM post_tag pt INNER JOIN reputations r ON r.post_id = pt.post_id INNER JOIN tags t ON pt.tag_id = t.id WHERE r.user_id = u.id ORDER BY sum(r.reputation) DESC LIMIT 2)
FROM users u
LEFT JOIN reputation r ON r.user_id = u.id
GROUP BY u.id, u.name, score, reputation
ORDER BY reputation, score;
答案 1 :(得分:-2)
你可以尝试一下。
SELECT DISTINCT u.*,
sum(r.score) as score,
sum(r.reputation) as reputation
GROUP_CONCAT(',', t.name) as tags
FROM users u
LEFT JOIN reputation r ON r.user_id = u.id
LEFT JOIN post_tag pt ON(pt.post_id=r.post_id)
LEFT JOIN tags t ON(t.id=pt.tag_id)
WHERE r.date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 1 WEEK)
GROUP BY u.id ,
ORDER BY reputation, score