我有一个只有ID和状态被写入的表,从未更新过,在这里我只想查询具有初始状态的ID,即只有ID为第一行的行,以便我可以对其进行处理状态发生变化。 如果处理正常,则将为这些ID写入新状态,下次我查询时,不应获得ID已成功处理的行。
示例:对于具有状态“ INITIAL”和“ DONE”的ID,我有两行,对于具有状态“ INITIAL”的第二个ID,我有另一行。 当我查询时,我只想获取第二个ID。
我尝试了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 btw:)
我在这里发现了许多类似的问题,但并非完全是这个问题,但是如果您知道一个,请直接将我引向另一个答案! :)
感谢帮助!
答案 0 :(得分:3)
一个选项,也许是最有效的,使用了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
的所有记录,但不能与状态为 other 的具有相同id
的另一条记录联接INITIAL
。
答案 1 :(得分:1)
因为INITIAL是第一个状态,所以我只选择了1行(使用count)来选择ID
SELECT id
FROM (SELECT id, state, COUNT(*) count
FROM states
GROUP BY id) as c
WHERE c.count = 1
AND c.state = 'INITIAL'
答案 2 :(得分:1)
使用具有封闭性的
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