我有一个pgsql模式,该模式的表中有两列:id和status。状态值是varchar类型,范围从'1'到'6'。我想选择仅具有特定状态的id的值,确切地说,一个id仅具有一个状态('1'),然后另一个具有两个值('1'和s'2'),然后另一个仅具有三个值(' 1”,“ 2”和“ 3”)等等。
这是用于pgsql数据库的。我曾尝试使用内部查询与同一张表联接。
select *
from srt s
join ( select id
from srt
group by id
having count(distinct status) = 2
) t on t.id = s.id
where srt.status in ('1', '2')
limit 10
我用它来获取仅具有状态值1和2(并且没有任何具有状态值3、4、5、6的行)的ID,但是没有得到预期的结果
预期结果将是这样
id status
123 1
234 1
234 2
345 1
345 2
345 3
456 1
456 2
456 3
456 4
567 1
567 2
567 3
567 4
567 5
678 1
678 2
678 3
678 4
678 5
678 6
答案 0 :(得分:0)
在子查询中移动您的where条件-
select *
from srt s
join ( select id
from srt
where status in ('1', '2')
group by id
having count(distinct status) = 2
) t on t.id = s.id
limit 10
答案 1 :(得分:0)
要标识具有连续状态的ID,您可以执行以下操作:
select id, max(status) as max_status
from srt s
group by id
having min(status) = 1 and
max(status::int) = count(*);
然后,您可以使用distinct on
将其缩小为一个示例,并使用join
来获得结果:
select s.*
from srt s join
(select distinct on (max(status)) id, max(status) as max_status
from srt s
group by id
having min(status) = 1 and
max(status::int) = count(*)
order by max_status asc
) ss
on ss.id = s.id
order by ss.max_status, s.status;
答案 2 :(得分:0)
这是一个棘手的问题。我的解决方案是首先指定您要匹配的“目标状态”列表:
with target_statuses(s) as ( values (1),(2),(3) )
然后将您的srt
表加入其中并计算按id
分组的出现次数。
with target_statuses(s) as ( values (1),(2),(3) )
select id, count(*), row_number() OVER (partition by count(*) order by id) rownum
from srt
join target_statuses on status=s
group by id
)
此查询还捕获行号,稍后我们将使用该行号将其限制为具有一个匹配项的第一个id,具有两个匹配项的第一个id,等等。请注意order by
子句...我假设您在每种情况下都首先需要按字母顺序排列的最低编号,但是您可以更改它。
由于您无法将窗口函数放在HAVING
子句中,因此我将整个结果包装在ids_and_counts_of_statuses
处,并执行后续查询,并将其与srt
重新合并表以输出它:
with ids_and_counts_of_statuses as(
with target_statuses(s) as ( values (1),(2),(3) )
select id, count(*), row_number() OVER (partition by count(*) order by id) rownum
from srt
join target_statuses on status=s
group by id
)
select srt.id, srt.status
from ids_and_counts_of_statuses
join srt on ids_and_counts_of_statuses.id=srt.id
where rownum=1;
请注意,我只是将您的varchar值更改为整数,因此我不必键入太多标点符号。它可以工作,下面是一个示例:https://www.db-fiddle.com/f/wwob31uiNgr9aAkZoe1Jgs/0