0

我有四个表用户、角色、用户角色和电子邮件。我需要开发一个查询来检索用户信息(用户名、姓氏和名字)、用户电子邮件地址(来自电子邮件表)和所有角色的聚合列表(它连接到用户表,有很多-多表用户角色)。我开发了下面的查询,它有一个问题。聚合列表具有重复的角色名称条目。

SELECT DISTINCT ON (u.username)
    u.username AS "Username", u.lastname AS "Last Name", u.firstname AS "First Name", e.name AS "Email Address"
    , string_agg(r.name, ';'  ORDER BY r.name) AS "Roles"
FROM    users u
    LEFT OUTER JOIN user_role ur ON (u.id=ur.user_id)
    LEFT OUTER JOIN roles r ON (ur.role_id = r.id)
    INNER JOIN email e ON e.user_id = u.id
WHERE   u.active = 1 AND length(r.name) > 0 AND r.active = 1 AND ur.active = 1
GROUP BY u.username, u.lastname, u.firstname, e.name
ORDER BY u.username

如果我注释掉内部电子邮件连接和关联的电子邮件字段(见下文),我会在 string_agg 中获得正确的角色名称。

SELECT DISTINCT ON (u.username)
    u.username AS "Username", u.lastname AS "Last Name", u.firstname AS "First Name",
--  e.name AS "Email Address"
    , string_agg(r.name, ';'  ORDER BY r.name) AS "Roles"
FROM    users u
    LEFT OUTER JOIN user_role ur ON (u.id=ur.user_id)
    LEFT OUTER JOIN roles r ON (ur.role_id = r.id)
--  INNER JOIN email e ON e.user_id = u.id
WHERE   u.active = 1 AND length(r.name) > 0 AND r.active = 1 AND ur.active = 1
GROUP BY u.username, u.lastname, u.firstname, 
--  e.name
ORDER BY u.username
4

1 回答 1

0

这可能会解决问题。这是一个有根据的猜测。问题中没有足够的信息。

SELECT DISTINCT ON (u.username)
        u.username AS "Username"
      , u.lastname AS "Last Name"
      , u.firstname AS "First Name"
      , e.emails AS "Email Addresses"
      , string_agg(r.name, ';'  ORDER BY r.name) AS "Roles"
FROM    users u
LEFT    JOIN user_role ur ON u.id = ur.user_id
LEFT    JOIN roles     r  ON ur.role_id = r.id
LEFT    JOIN (
   SELECT user_id, string_agg(name, ', ') AS emails
   FROM   email
   GROUP  BY 1
   ) e  ON e.user_id = u.id
WHERE  u.active = 1
AND    r.name  ''
AND    r.active = 1
AND    ur.active = 1
GROUP  BY u.username, u.lastname, u.firstname, e.emails 
ORDER  BY u.username

旁白:r.name <> ''和 一样length(r.name) > 0,只是更快。

这是否应该是LEFT JOIN电子邮件而不是 aJOIN是一个不相关的问题。
但我想它应该是,所以我也改变了它。

于 2013-04-08T23:06:05.730 回答