Есть ли способ объединить все два запроса и удалить повторяющиеся строки - PullRequest
0 голосов
/ 24 марта 2020

Я работаю с разрешениями, у меня есть таблица user_screens, в которой хранятся разрешения users;
У меня есть таблица segment_screens, которые определяют, на какие экраны пользователь может иметь разрешения. Мне нужно получить все экраны, которые есть в segment_screens. Если segment_screen.screen_id находится в таблице user_screens, возьмите строку таблицы user_screens, если segment_screen.screen_id отсутствует в таблице user_screens, мне нужно вернуть нулевой идентификатор и разрешения как false.

Я пытаюсь так:

SELECT DISTINCT
          user_screens.id,
          s.description,
          user_screens.screen_id,
          user_screens.allow_read,
          user_screens.allow_create,
          user_screens.allow_update,
          user_screens.allow_delete
          FROM
          (SELECT id,
            screen_id,
            allow_read,
            allow_create,
            allow_update,
            allow_delete
          FROM user_screens
          WHERE user_id = 1
          UNION ALL SELECT
                      NULL AS id,
                      s.id,
                      'f' :: BOOLEAN AS allow_read,
                      'f' :: BOOLEAN AS allow_create,
                      'f' :: BOOLEAN AS allo_update,
                      'f' :: BOOLEAN AS allow_delete
          FROM users u
          LEFT JOIN user_companies uc ON uc.user_id = u.id
          LEFT JOIN companies c ON c.id = uc.company_id
          LEFT JOIN segments seg ON seg.id = c.segment_id
          LEFT JOIN segment_screens segscreen ON segscreen.segment_id = seg.id
          LEFT JOIN screens s ON s.id = segscreen.screen_id) user_screens
          LEFT JOIN screens s ON s.id = user_screens.screen_id
          ORDER  BY s.description ASC

Но так, когда у меня есть строка в user_screen и в segment_screen, я беру эти две записи, и мне нужна только строка, которая находится в user_screens со строками, которых нет в user_screens, но есть в сегменте_экранов.

Это мой результат:

В желтом - запись, которая мне нужна сохранить, а запись - это элемент, который мне не нужен, но уже находится в user_screens.

Как я могу это сделать?

@ Edit:

Пробовал с DISTINCT ON и ORDER BY:

`SELECT DISTINCT ON (screen_id) screen_id,
          user_screens.id,
          s.description,
          user_screens.screen_id,
          user_screens.allow_read,
          user_screens.allow_create,
          user_screens.allow_update,
          user_screens.allow_delete
          FROM
          (SELECT id,
            screen_id,
            allow_read,
            allow_create,
            allow_update,
            allow_delete
          FROM user_screens
          WHERE user_id = ?
          order by screen_id, (id is not null) desc
          UNION ALL SELECT
                      NULL AS id,
                      s.id,
                      'f' :: BOOLEAN AS allow_read,
                      'f' :: BOOLEAN AS allow_create,
                      'f' :: BOOLEAN AS allo_update,
                      'f' :: BOOLEAN AS allow_delete
          FROM users u
          LEFT JOIN user_companies uc ON uc.user_id = u.id
          LEFT JOIN companies c ON c.id = uc.company_id
          LEFT JOIN segments seg ON seg.id = c.segment_id
          LEFT JOIN segment_screens segscreen ON segscreen.segment_id = seg.id
          LEFT JOIN screens s ON s.id = segscreen.screen_id) user_screens
          LEFT JOIN screens s ON s.id = user_screens.screen_id
          ORDER BY s.description ASC
      `

1 Ответ

1 голос
/ 24 марта 2020

Это не дубликаты. Но если вы хотите сохранить одну запись для некоторого значения в столбце, вы можете использовать distinct on:

select distinct on (screen_id) . . .
from . . .
order by screen_id, (id is not null) desc;
...