【问题标题】:Remove row duplicates and get the highest value with PostgreSQL删除行重复并使用 PostgreSQL 获得最高值
【发布时间】:2012-12-16 02:59:06
【问题描述】:

使用以下查询

SELECT
  users.id,
  users.username,
  users.email,
  groups.permission
FROM users
INNER JOIN memberships ON users.id = memberships.user_id
INNER JOIN groups ON memberships.group_id = groups.id
INNER JOIN groupings ON groups.id = groupings.group_id
WHERE groupings.repo_id = 1
GROUP BY users.id, groups.permission
ORDER BY users.id

我得到以下行:

----+---------------------------+-----------------------------------------+------------
 id |         username          |                  email                  | permission 
----+---------------------------+-----------------------------------------+------------
  2 | viva_leuschke0            | viva_leuschke0@ritchiealtenwerth.org    | 1
  2 | viva_leuschke0            | viva_leuschke0@ritchiealtenwerth.org    | 2
  3 | loyce_herman1             | herman1.loyce@bednar.com                | 1
  3 | loyce_herman1             | herman1.loyce@bednar.com                | 3
  4 | verona_vandervort2        | verona.vandervort2@mante.biz            | 1
  4 | verona_vandervort2        | verona.vandervort2@mante.biz            | 2
  4 | verona_vandervort2        | verona.vandervort2@mante.biz            | 3
  5 | bruen3_ms_hans            | ms.bruen3.hans@bechtelar.net            | 1
  5 | bruen3_ms_hans            | ms.bruen3.hans@bechtelar.net            | 2
  5 | bruen3_ms_hans            | ms.bruen3.hans@bechtelar.net            | 3
----+---------------------------+-----------------------------------------+------------

问题是:如何调整此查询以返回唯一行,按最高权限值过滤?比如:

----+---------------------------+-----------------------------------------+------------
 id |         username          |                  email                  | permission 
----+---------------------------+-----------------------------------------+------------
  2 | viva_leuschke0            | viva_leuschke0@ritchiealtenwerth.org    | 2
  3 | loyce_herman1             | herman1.loyce@bednar.com                | 3
  4 | verona_vandervort2        | verona.vandervort2@mante.biz            | 3
  5 | bruen3_ms_hans            | ms.bruen3.hans@bechtelar.net            | 3
----+---------------------------+-----------------------------------------+------------

我使用的是 PostgreSQL 9.1。

更新:通过使用DISTINCT ON 子句,我能够得到我想要的。

SELECT DISTINCT ON(users.id)
  users.id,
  users.username,
  users.email,
  groups.permission
FROM users
INNER JOIN memberships ON users.id = memberships.user_id
INNER JOIN groups ON memberships.group_id = groups.id
INNER JOIN groupings ON groups.id = groupings.group_id
WHERE groupings.repo_id = 1
GROUP BY users.id, groups.permission
ORDER BY 
  users.id ASC, 
  groups.permission DESC

这是最好的方法吗?

【问题讨论】:

  • 我想您将找到的(有效!)答案发布为 answer 并接受。这是推荐的方式:您可以回答自己的问题。
  • 呵呵呵呵呵呵...实际上,我是在问这个查询是不是最适合这项工作。
  • 好像我错过了两件事。您添加的问题和添加的查询中的不完美之处。不错,干净的问题,顺便说一句。

标签: sql postgresql distinct inner-join greatest-n-per-group


【解决方案1】:

仔细检查后,您的查询可以(并且应该)改进:


SELECT DISTINCT ON (u.id)
      ,u.id
      ,u.username
      ,u.email
      ,g.permission
FROM   users       u
JOIN   memberships m  ON m.user_id = u.id
JOIN   groups      g  ON g.id = m.group_id
JOIN   groupings   gi ON gi.group_id = g.id 
WHERE  gi.repo_id = 1
GROUP  BY u.id, g.permission
ORDER  BY u.id, g.permission DESC

GROUP BY 没用。仅DISTINCT ON 就为您提供了独特的users.id。去掉GROUP BY,你会得到同样的结果,只是更快。

您可能希望向ORDER BY 添加更多列,以决定选择哪一行,其中每个id 有多个共享最高permission。您拥有它的方式,您可以随意选择这种情况(前提是它可以发生)。

My reference answer for this query technique has more explanation, a benchmark and links.

【讨论】:

  • 嘿!非常感谢您的链接。它还包括有关如何添加正确索引的信息。
猜你喜欢
  • 2023-03-30
  • 2013-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-02
  • 1970-01-01
相关资源
最近更新 更多