2012-05-05 44 views
1

我试图让它选择显示优先级最高的组。 问题是它选择ID最低的组,我不确定如何选择具有最高显示优先级的组。选择显示优先级最高的多个用户组

SQL查询看起来是这样的:

SELECT xf_user_group_relation.user_id , 
     xf_user_field_value.field_value, 
     xf_user_group_relation.user_group_id, 
     MAX(xf_user_group.display_style_priority) AS display_style_priority 
FROM xf_user_group_relation 
    INNER JOIN xf_user_group ON xf_user_group_relation.user_group_id = xf_user_group.user_group_id 
    INNER JOIN xf_user_field_value ON xf_user_group_relation.user_id = xf_user_field_value.user_id 
WHERE xf_user_group.display_style_priority >= 500 
     AND field_id = 'minecraft' 
     AND xf_user_group_relation.user_group_id NOT IN(21,22) 
GROUP BY xf_user_group_relation.user_id, 
     xf_user_field_value.field_value; 

的群体是在xf_user_group结构为:

user_group_id   int(10)  AUTO_INCREMENT 
title     varchar(50) 
display_style_priority int(10) 
user_css     text 
user_title    varchar(100) 
+0

哪里列'field_id'从何而来?你希望总体上具有最高显示优先级的组?或每个用户? –

+0

它是每个用户,field_id来自xf_user_field_value – BlackVoid

回答

1

MySql的errorneously让您汇总值,而不specifing所有非聚集在GROUP BY中。所以它自己选择为user_group_id显示什么价值。 要获得您需要的结果,您必须获得每个用户的最大display_style_priority,然后将user_id和value加回到原始表中以对其进行过滤。有两种形式则可以使用,加入

SELECT * 
FROM xf_user_group_relation 
    INNER JOIN xf_user_group 
     ON xf_user_group_relation.user_group_id = xf_user_group.user_group_id 
    INNER JOIN xf_user_field_value 
     ON xf_user_group_relation.user_id = xf_user_field_value.user_id 
    INNER JOIN 
    (
     SELECT r2.user_id, MAX(g2.display_style_priority) display_style_priority 
     FROM xf_user_group_relation r2 
     INNER JOIN xf_user_group g2 
      ON r2.user_group_id = g2.user_group_id 
     GROUP BY r2.user_id 
    ) maxDSP 
     ON xf_user_group_relation.user_id = maxDSP.user_id 
     AND xf_user_group.display_style_priority = maxDSP.display_style_priority 
WHERE xf_user_group.display_style_priority >= 500 
     AND field_id = 'minecraft' 
     AND xf_user_group_relation.user_group_id NOT IN(21,22) 

而且比较最大的subqery:

SELECT * 
FROM xf_user_group_relation 
    INNER JOIN xf_user_group 
     ON xf_user_group_relation.user_group_id = xf_user_group.user_group_id 
    INNER JOIN xf_user_field_value 
     ON xf_user_group_relation.user_id = xf_user_field_value.user_id 
WHERE xf_user_group.display_style_priority = 
     (SELECT MAX(g2.display_style_priority) 
     FROM xf_user_group_relation r2 
     INNER JOIN xf_user_group g2 
      ON r2.user_group_id = g2.user_group_id 
     WHERE r2.user_id = xf_user_group_relation.user_id 
    ) 
     AND xf_user_group.display_style_priority >= 500 
     AND field_id = 'minecraft' 
     AND xf_user_group_relation.user_group_id NOT IN(21,22) 

现场演示是在Sql Fiddle

0

您可以添加order by

ORDER BY xf_user_group_relation.user_id DESC 
0

这是查询配对ID最低的组,并说它具有最高的display_style_priorty?

如果是这样的子查询可以照顾,对你,但我不知道你所得到的结果是什么,期望的结果是

0

准确地说,这仅返回每个用户具有最高显示优先级的组(user_id, field_value),而不是。我认为这是你想要什么:

SELECT r.user_id, 
     x.field_value, 
     r.user_group_id, 
     x.max_disp AS display_style_priority 
FROM (
    SELECT r.user_id, v.field_value, max(g.display_style_priority) AS max_disp 
    FROM xf_user_group_relation r 
    JOIN xf_user_field_value v USING (user_id) 
    JOIN xf_user_group   g USING (user_group_id) 
    WHERE g.display_style_priority >= 500 
    AND v.field_id = 'minecraft' 
    AND r.user_group_id NOT IN (21,22) 
    GROUP BY r.user_id, v.field_value 
    ) x 
JOIN xf_user_group_relation r USING (user_id) 
JOIN xf_user_group g ON g.display_style_priority = x.max_disp 
        AND g.user_group_id = r.user_group_id 

如果一个用户可以拥有多个组具有相同display_style_priority,这可以每(user_id, field_value)返回多行共享相同的最高优先显示。


其他RDBMS(如PostgreSQL,MSSQL或Oracle)具有窗口功能,大大简化了这样的任务。

在PostgreSQL,您的查询可能会像这样工作:

SELECT DISTINCT 
     r.user_id 
     ,v.field_value 
     ,last_value(g.user_group_id) OVER w AS user_group_id 
     ,last_value(g.display_style_priority) OVER w AS display_style_priority 
FROM xf_user_group_relation r 
JOIN xf_user_field_value v USING (user_id) 
JOIN xf_user_group   g USING (user_group_id) 
WHERE g.display_style_priority >= 500 
AND v.field_id = 'minecraft' 
AND r.user_group_id NOT IN (21,22) 
WINDOW w AS (PARTITION BY r.user_id, v.field_value 
      ORDER BY g.display_style_priority); 

Introduction to window functions in the PostgreSQL manual.