2015-04-26 2 views
1

У меня есть две таблицы в MySQL: одна называется gtfsws_users, которая содержит пользователей для системы, которую я разрабатываю, а другая - gtfsws_repository_users, которая содержит роли для этих пользователей.Как «удалить дубликаты» из запроса UNION

gtfsws_users имеет следующие поля: электронную почту, пароль, имя, is_admin и включен. gtfsws_repository_users имеет: user_email, repository_id и роль.

role - целое число, определяющее привилегии в репозитории GTFS (данные общественного транспорта, не относящиеся к моей проблеме).

Одна важная вещь в том, что каждый администратор accont (то есть, каждый пользователь, который имеет is_admin флаг установлен как 1 в 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:

('[email protected]', '*****', 'Real name', 1, 1)

А также пользователь зарегистрирован в gtfsws_repository_users, как это:

('[email protected]', 2, 10)

Когда я делаю SELECT в MySQL (с помощью UNION для добавления всех администраторов) Я получаю:

('[email protected]', 'Real name', 1, 1, 10) 
('[email protected]', 'Real name', 1, 1, NULL) 

Что мне нужно сделать, это фильтр, что таблицы для удаления дубликатов, что получает только:

('[email protected]', 'Real name', 1, 1, NULL) 

Да, получение NULL как роль (так как он будет проигнорирован, как пользователь администратор).

У кого-нибудь есть ключ к тому, как этого достичь? Большое спасибо.

EDIT: Хорошо, благодаря предложению Катрин, я получаю некоторый прогресс. Я получаю один ряд, но он совпадает с номером role. Любой способ сохранить один с ролью NULL вместо определенного?

+0

использование 'SELECT * FROM (ваш запрос здесь) AS х GROUP BY x.email' предполагающей электронной почты является уникальным для каждого пользователя – Sharky

+0

Благодаря @KatrinRaimond, да' электронная почта' уникальна. Я использую его как идентификатор для каждого пользователя. Я попробую. Благодарю. –

ответ

0

Поскольку функции агрегата игнорируют нулевые значения, вы можете преобразовать null в число, которое может быть извлечено как min или max.
Предполагая, что все ваши роли больше, чем 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 
+0

Это работает. Спасибо! –