Как я могу в SQL фильтровать строки, которые имеют только начальную строку на идентификатор? - PullRequest
0 голосов
/ 05 октября 2018

У меня есть таблица с идентификатором и состоянием, которые только записываются, но никогда не обновляются, где я хочу запрашивать только идентификаторы с начальным состоянием, то есть только строки идентификаторов с записанной первой строкой, чтобы я мог их обработатьдля изменения состояния вниз по линии.Если обработка идет нормально, для этих идентификаторов пишется новое состояние, и в следующий раз, когда я сделаю запрос, я не должен получить строки с идентификаторами, которые были успешно обработаны.

Пример: у меня есть две строки для идентификатора с состоянием 'INITIAL 'и' DONE 'и еще одна строка для второго идентификатора с состоянием' INITIAL '.Когда я запрашиваю, я хочу получить только второй идентификатор.

Я пробовал с group by, но так как я не могу фильтровать состояние, не группируя его тоже, поэтому оно не работает так, как я планировал.

Я пришел с этим запросом, но действительно ли это как его решить?

select id, state from states s1 where state = 'INITIAL' and not exists
(select 1 from states s2 where s2.state != 'INITIAL' and s2.id = s1.id);

Я использую Postgres: :)

Я нашел многоподобные вопросы здесь, но не совсем так, но, пожалуйста, направьте меня на другой ответ, если вы знаете один!:)

Спасибо за помощь!

Ответы [ 3 ]

0 голосов
/ 05 октября 2018

Так как INITIAL является первым состоянием, я сделал выбор идентификаторов только с 1 строкой (используя счетчик)

SELECT id
FROM (SELECT id, state, COUNT(*) count
      FROM states
      GROUP BY id) as c
WHERE c.count = 1 
  AND c.state = 'INITIAL'
0 голосов
/ 05 октября 2018

Использовать с Cluase

select id from states s1 
group by id
having sum(case when state='INITIAL' then 1 else 0 end)=1
and sum(case when state<>'INITIAL' then 1 else 0 end)=0
0 голосов
/ 05 октября 2018

Один вариант, возможно, самый эффективный, использует предложение NOT EXISTS:

SELECT id, state
FROM states s1
WHERE
    state = 'INITIAL' AND
    NOT EXISTS (SELECT 1 FROM states s2 WHERE s1.id = s2.id AND s2.state <> 'INITIAL');

Мы также можем использовать агрегацию здесь:

SELECT s1.id, s1.state
FROM states s1
INNER JOIN
(
    SELECT id
    FROM states
    GROUP BY id
    HAVING COUNT(CASE WHEN state <> 'INITIAL' THEN 1 END) = 0
) s2
    ON s1.id = s2.id;

Другой вариант - самостоятельное объединение:

SELECT s1.id, s1.state
FROM states s1
LEFT JOIN states s2
    ON s1.id = s2.id AND s2.state <> 'INITIAL'
WHERE s1.state = 'INITIAL' AND s2.id IS NULL;

Этот запрос работает, сохраняя все записи, в которых id равен INITIAL, но не может присоединиться к другой записи, имеющей то же id с состоянием , отличное , чемINITIAL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...