首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从只包含另一列中的特定值而不包含其他值的列中选择值?

如何从只包含另一列中的特定值而不包含其他值的列中选择值?
EN

Stack Overflow用户
提问于 2019-08-02 01:15:18
回答 3查看 30关注 0票数 0

我有一个pgsql模式,它有一个表,其中有两列: id和status。状态值是从“1”到“6”的varchar类型。我想选择只有特定状态的id的值,确切地说,一个id只有一个状态('1'),然后另一个id有两个值('1‘和'2'),然后另一个只有三个值('1','2’和'3'),依此类推。

这是针对pgsql数据库的。我尝试过对同一个表使用内部查询连接。

代码语言:javascript
复制
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,但是没有得到预期的结果

预期的结果如下所示

代码语言:javascript
复制
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
EN

回答 3

Stack Overflow用户

发布于 2019-08-02 01:22:25

将where条件移动到子查询中-

代码语言:javascript
复制
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
票数 0
EN

Stack Overflow用户

发布于 2019-08-02 01:37:56

要标识具有连续状态的ids,您可以执行以下操作:

代码语言:javascript
复制
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带来您的结果:

代码语言:javascript
复制
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;
票数 0
EN

Stack Overflow用户

发布于 2019-08-02 01:47:27

这是一个棘手的问题。我的解决方案是首先指定要匹配的“目标状态”列表:

代码语言:javascript
复制
with target_statuses(s) as ( values (1),(2),(3) )

然后将您的srt表连接到该表中,并计算按id分组的匹配项。

代码语言:javascript
复制
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子句...我假设您在每种情况下都想要按字母顺序排列的最低id,但是您可以更改它。

由于不能将窗口函数放在HAVING子句中,因此我在ids_and_counts_of_statuses中包装了整个结果,并执行了一个后续查询,将其与srt表重新联接起来,以输出结果:

代码语言:javascript
复制
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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57314008

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档