如何从UNION查询中“删除重复项”

时间:2015-04-26 09:10:29

标签: mysql

我在MySQL中有两个表:一个名为gtfsws_users,其中包含我正在开发的系统的用户和另一个名为gtfsws_repository_users的用户,其中包含这些用户的角色。

gtfsws_users包含以下字段:电子邮件密码名称 is_admin 启用即可。 gtfsws_repository_users具有: user_email repository_id 角色

role是一个整数,用于定义GTFS存储库的权限(公共交通数据,与我的问题无关)。

一个重要的事情是每个管理员accont (即,is_admin1标记设置为gtfsws_users的每个用户都具有完全访问权限到所有存储库。

现在,只有在gtfsws_repository_users中注册的用户才能访问在那里定义的特定存储库(当然,除非他们是管理员)。一个用户可以拥有多个他/她可以访问的存储库。

我要做的是让所有有权访问特定存储库的用户(用户拥有哪种role无关紧要,我只想知道他们是否可以访问存储库)。所以我正在编写这个SQL语句来获取它们:

(
    SELECT DISTINCT
        gtfsws_users.email AS email,
        gtfsws_users.name AS name,
        gtfsws_users.is_admin AS is_admin,
        gtfsws_users.enabled AS enabled,
        gtfsws_repository_users.role AS role
    FROM
        gtfsws_users
    INNER JOIN
        gtfsws_repository_users
    ON
        gtfsws_users.email = gtfsws_repository_users.user_email
    WHERE
        gtfsws_repository_users.repository_id = '2'
)
UNION
(
    SELECT
        email,
        name,
        is_admin,
        enabled,
        null AS role
    FROM
        gtfsws_users
    WHERE
        is_admin = 1
)

现在,这适用于可以访问不同存储库的用户。它也得到了所有管理员。

问题是当我的管理员也在gtfsws_repository_users中注册时,因为我将其复制了。

例如,我在gtfsws_users

中有这个

('test@test.com', '*****', 'Real name', 1, 1)

此外,用户在gtfsws_repository_users中注册为:

('test@test.com', 2, 10)

当我在MySQL中SELECT(使用UNION添加所有管理员)时,我得到:

('test@test.com', 'Real name', 1, 1, 10)
('test@test.com', 'Real name', 1, 1, NULL)

我需要做的是过滤该表以删除重复项,即仅获取:

('test@test.com', 'Real name', 1, 1, NULL)

是的,将NULL作为角色(因为用户是管理员时会被忽略)。

有人知道如何实现这一目标吗? 非常感谢。

编辑:好的,多亏了Katrin的建议,我正在取得一些进展。我确实获得了一行,但它是定义了role数字的那一行。有没有办法保留NULL角色而不是定义角色的角色?

1 个答案:

答案 0 :(得分:0)

由于聚合函数忽略空值,因此可以将null转换为可以提取为最小值或最大值的数字 假设您的所有角色都大于0:

SELECT email, name, is_admin, enabled, nullif(min(coalesce(role, 0)), 0) as role
from
((
    SELECT DISTINCT
        gtfsws_users.email AS email,
        gtfsws_users.name AS name,
        gtfsws_users.is_admin AS is_admin,
        gtfsws_users.enabled AS enabled,
        gtfsws_repository_users.role AS role
    FROM
        gtfsws_users
    INNER JOIN
        gtfsws_repository_users
    ON
        gtfsws_users.email = gtfsws_repository_users.user_email
    WHERE
        gtfsws_repository_users.repository_id = '2'
)
UNION
(
    SELECT
        email,
        name,
        is_admin,
        enabled,
        null AS role
    FROM
        gtfsws_users
    WHERE
        is_admin = 1
)) as Q
GROUP BY email, name, is_admin, enabled