我目前正在使用点系统,该系统使用下面的查询列出一个类别中的点数最多的人或其下方的任何类别(使用'category_relations表'中的'links_to'和'links_from').
SELECT u.name,
pa.user_id,
SUM(IF(pa.plus = '1', pa.points_amount, 0)) -
SUM(IF(pa.plus = '0', pa.points_amount, 0)) AS points
FROM points_awarded pa, Users u
WHERE u.user_id = pa.user_id AND
(
category_id = '" . $category_id . "' OR
category_id IN
(
SELECT links_to
FROM category_relations
WHERE links_from = '" . $category . "'
)
)
GROUP BY user_id
ORDER BY points DESC
LIMIT 50
Run Code Online (Sandbox Code Playgroud)
我现在要做的是切换此查询以查找特定用户的所有类别,而不是查找特定类别的所有用户.以下是我尝试使用的查询,但这仅包括类别的点,而不是下面的子类别.
SELECT u.name,
pa.user_id,
pa.category_id,
SUM(IF(pa.plus = '1', pa.points_amount, 0)) -
SUM(IF(pa.plus = '0',pa.points_amount, 0)) AS points
FROM points_awarded pa, Users u
WHERE u.user_id = pa.user_id AND
u.user_id = '" . $user_id . "'
GROUP BY pa.category_id
ORDER BY points DESC
LIMIT 50
Run Code Online (Sandbox Code Playgroud)
从您的示例查询中,我能够推导出表结构的简化,这为我提供了足够的信息来回答您的问题.您可以使用此解决方案:
SELECT a.user_id,
a.name,
b.category_id,
SUM(IF(d.plus = '1', d.points_amount, 0)) -
SUM(IF(d.plus = '0', d.points_amount, 0)) AS points
FROM Users a
JOIN points_awarded b ON a.user_id = b.user_id
JOIN (
SELECT links_from, links_to
FROM category_relations
UNION
SELECT links_from, links_from
FROM category_relations
) c ON b.category_id = c.links_from
JOIN points_awarded d ON c.links_to = d.category_id
WHERE a.user_id = $user_id
GROUP BY a.user_id,
a.name,
b.category_id
ORDER BY points DESC
LIMIT 50
Run Code Online (Sandbox Code Playgroud)
$user_id查询的用户ID参数在哪里.
基本上,此查询的关键组件是我们选择category_relations表的方式.
由于您需要子类别点的总和(按每个父类别)加上它们各自的父类别的点,我们可以垂直地通过父类别来处理UNION它,并且基本上使它成为自身的子类别.这将很好地考虑到GROUP BY和SUM.
假设我们有一些(简化的)数据,如下所示:
Users
------------------
user_id | name
433 | Zane
Run Code Online (Sandbox Code Playgroud)
points_awarded
------------------
user_id | category_id | plus | points_amount
433 | 1 | 1 | 785
433 | 2 | 1 | 871
433 | 3 | 1 | 236
433 | 4 | 0 | 64
433 | 5 | 0 | 12
433 | 7 | 1 | 897
433 | 8 | 1 | 3
433 | 9 | 0 | 48
433 | 10 | 1 | 124
433 | 14 | 0 | 676
Run Code Online (Sandbox Code Playgroud)
category_relations
------------------
links_from | links_to
1 | 2
1 | 3
1 | 4
5 | 8
5 | 9
7 | 10
7 | 14
Run Code Online (Sandbox Code Playgroud)
为了区分父类和子类,查询points_awarded使用表中的两个字段在category_relations表上执行自交叉引用连接.
如果我们只是按category_relations原样加入表UNION,那么我们得到的连接看起来就像(简化列):
category_id | points_amount | category_id | points_amount
1 | 785 | 2 | 871
1 | 785 | 3 | 236
1 | 785 | 4 | 64
5 | 12 | 8 | 3
5 | 12 | 9 | 48
7 | 897 | 10 | 124
7 | 897 | 14 | 676
Run Code Online (Sandbox Code Playgroud)
如您所见,最左边category_id是父类别,最右边category_id是各自的子类别.我们可以轻松地分组第一个category_id和SUM第二个points_amount......
但是等等,我们也需要包含父类别' points_amount!我们如何points_amount明确地将第一个进入第二个points_amount?这是UNION发挥作用的地方.
在我们执行自交叉引用连接之前,我们category_relations会对表进行子选择,以便稍微改变它:
SELECT links_from, links_to FROM category_relations
UNION
SELECT links_from, links_from FROM category_relations
Run Code Online (Sandbox Code Playgroud)
然后导致:
category_relations (subselected)
------------------
links_from | links_to
1 | 1 <-- parent category
1 | 2
1 | 3
1 | 4
5 | 5 <-- parent category
5 | 8
5 | 9
7 | 7 <-- parent category
7 | 10
7 | 14
Run Code Online (Sandbox Code Playgroud)
我们基本上将每个父类别作为其自身的子类别.我们在我们的连接中使用this的结果,然后产生:
category_id | points_amount | category_id | points_amount
1 | 785 | 1 | 785
1 | 785 | 2 | 871
1 | 785 | 3 | 236
1 | 785 | 4 | 64
5 | 12 | 5 | 12
5 | 12 | 8 | 3
5 | 12 | 9 | 48
7 | 897 | 7 | 897
7 | 897 | 10 | 124
7 | 897 | 14 | 676
Run Code Online (Sandbox Code Playgroud)
在那里,现在将父类别考虑在内SUM,我们现在可以对第一个category_id进行分组,对第二个进行求和points_amount(忽略第一个points_amount,因为它是不相关的),为您提供所需的输出.
我很确定有一种更简单的方法可以通过加入category_relations表来做到这一点,但是很难看不到表的任何可视示例...我认为这应该有效:
SELECT u.name
,pa.user_id
,pa.category_id,
SUM(IF(pa.plus = '1', pa.points_amount, 0)) - SUM(IF(pa.plus = '0',pa.points_amount, 0)) AS points
FROM points_awarded pa
JOIN Users u
USING (user_id)
WHERE category_id IN(
SELECT links_to
FROM category_relations
WHERE links_from = (
SELECT category_id
FROM points_awarded
WHERE user_id = '" . $user_id . "'
)
)
GROUP BY pa.category_id
ORDER BY points DESC
LIMIT 50
Run Code Online (Sandbox Code Playgroud)
您在上面发布的示例中没有看到子类别,因为您没有包含category_relations 表中的记录。我们不是通过查询的category_id 查找链接的类别,而是使用子子查询来查找与用户关联的所有category_id。尝试一下,如果这不正确,请发布一些显示表数据的小片段。
| 归档时间: |
|
| 查看次数: |
267 次 |
| 最近记录: |