SQL Server:根据多个条件从组中选择特定行

Posted

技术标签:

【中文标题】SQL Server:根据多个条件从组中选择特定行【英文标题】:SQL Server : select specific row from groups based on multiple conditions 【发布时间】:2021-11-22 21:32:25 【问题描述】:

我有一个包含ID, Status, Date 列的表格。

我必须按IDDate 的年+月进行分组,以便为​​每个月和每个 ID 获得一行(它可以在一个月内有更多状态,每个状态都有自己的行)基于几个条件:

如果它有状态为“I”的行和/或状态为“R”的行和/或状态为“S”的行,它必须返回状态为“I”的行(仅应包括这 3 个状态,还有更多状态,但它们不应该受到影响——无论如何都应该出现)

如果它有状态为“R”的行和状态为“S”的行,那么它必须返回状态为“S”的行。

我尝试使用ROW_NUMBER 和自加入,但无济于事。

例如(2021 年 9 月,记得按年+月分组):

你能帮忙吗?

谢谢!

【问题讨论】:

让您轻松并有可能为您提供帮助:minimal reproducible example。 不要发布数据图像,将数据包含为 consumable text 和理想情况下 insert 语句并包含您的尝试。 【参考方案1】:

这主要只是选择正确的分组标准

SELECT
  t.ID,
  Month = EOMONTH(t.Date),
  Status = CASE WHEN COUNT(CASE WHEN t.Status = 'I' THEN 1 END) > 0 THEN 'I'
                WHEN COUNT(CASE WHEN t.Status = 'S' THEN 1 END) > 0 THEN 'S'
                WHEN COUNT(CASE WHEN t.Status = 'R' THEN 1 END) > 0 THEN 'R'
                ELSE MIN(Status) END
FROM YourTable t
GROUP BY
  t.ID,
  EOMONTH(t.Date),
  CASE WHEN Status NOT IN ('I','R','S') THEN Status END;

【讨论】:

谢谢。这对我帮助很大。【参考方案2】:

试试这个:

create table #test_group(id int, stat varchar(16), dt datetime default getdate())
insert into #test_group(id, stat) values (1, 'I')
insert into #test_group(id, stat) values (1, 'R')
insert into #test_group(id, stat) values (1, 'S')
insert into #test_group(id, stat) values (2, 'I')
insert into #test_group(id, stat) values (2, 'R')
insert into #test_group(id, stat) values (2, 'S')
insert into #test_group(id, stat) values (2, 'O')
insert into #test_group(id, stat) values (3, 'I')
insert into #test_group(id, stat) values (3, 'R')
insert into #test_group(id, stat) values (4, 'I')
insert into #test_group(id, stat) values (4, 'R')
insert into #test_group(id, stat) values (4, 'O')
insert into #test_group(id, stat) values (5, 'R')
insert into #test_group(id, stat) values (5, 'S')
insert into #test_group(id, stat) values (6, 'R')
insert into #test_group(id, stat) values (6, 'S')
insert into #test_group(id, stat) values (6, 'O')
insert into #test_group(id, stat) values (7, 'O')
insert into #test_group(id, stat) values (7, 'Z')
insert into #test_group(id, stat) values (7, 'F')
insert into #test_group(id, stat) values (8, 'I')
insert into #test_group(id, stat) values (8, 'R')
insert into #test_group(id, stat) values (8, 'S')
insert into #test_group(id, stat) values (8, 'I')
insert into #test_group(id, stat) values (8, 'R')
insert into #test_group(id, stat) values (8, 'S')
insert into #test_group(id, stat) values (8, 'R')
insert into #test_group(id, stat) values (8, 'S')
insert into #test_group(id, stat) values (8, 'S')
insert into #test_group(id, stat) values (8, 'O')
insert into #test_group(id, stat) values (8, 'Z')
insert into #test_group(id, stat) values (8, 'F')
insert into #test_group(id, stat) values (9, 'R')
insert into #test_group(id, stat) values (9, 'O')
insert into #test_group(id, stat) values (9, 'Z')
insert into #test_group(id, stat) values (9, 'F')
insert into #test_group(id, stat) values (9, 'S')
insert into #test_group(id, stat) values (10, 'R')
insert into #test_group(id, stat) values (10, 'O')
select * from #test_group
select id, DATEPART(year,dt)dtY,datepart(month, dt)dtM, 
case when min(stat) = 'I' then 'I' else case when max(stat) = 'S' then 'S' else 'R' end end stat
from #test_group where stat in ('I','R','S')group by id, DATEPART(year,dt),datepart(month, dt)
union all 
select id, DATEPART(year,dt)dtY,datepart(month, dt)dtM, stat
from #test_group where stat not in ('I','R','S')group by id, DATEPART(year,dt),datepart(month, dt), stat
order by dty,dtm,id,stat
drop table #test_group

【讨论】:

以上是关于SQL Server:根据多个条件从组中选择特定行的主要内容,如果未能解决你的问题,请参考以下文章

Oracle SQL:从组中选择最大值和最小值

仅从组中选择第一行的 SQL 模式

根据其他列的顺序从组中选择一个值

如果选择字段,则从组中获取所有选定的选项

XSLT / Muenchian 分组:如何从组中选择具有某些子元素的元素?

SQL Server 2008 R2 在特定条件下选择特定行