2

使用以下查询

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

这是最好的方法吗?

4

1 回答 1

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。以您拥有它的方式,您可以随意选择这种情况(前提是它可以发生)。

我对此查询技术的参考答案有更多解释、基准和链接。

于 2012-12-16T05:22:45.083 回答