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)
4

4 回答 4

1

MySql 错误地允许您聚合值而不在 GROUP BY 中指定所有非聚合。所以它自己选择为 user_group_id 显示什么值。要获得所需的结果,必须为每个用户获得最大 display_style_priority,然后将 user_id 和 value 连接回原始表以过滤它们。您可能会使用两种形式,join

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)

与子查询中的最大值进行比较:

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

于 2012-05-05T17:20:17.157 回答
0

你可以加order by

ORDER BY xf_user_group_relation.user_id DESC
于 2012-05-05T16:10:57.953 回答
0

此查询是否将具有最低 ID 的组配对并说它具有最高的 display_style_priorty?

如果是这样,子查询可以为您处理,但我不确定您得到的结果是什么以及所需的结果是什么

于 2012-05-05T16:51:00.810 回答
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);

PostgreSQL 手册中的窗口函数介绍。

于 2012-05-05T17:25:56.703 回答