【问题标题】:TSQL define group statuses based on group row statusesTSQL 根据组行状态定义组状态
【发布时间】:2019-08-07 09:45:39
【问题描述】:

您有什么想法可以根据组行状态定义组状态或我应该在谷歌上搜索什么? 在下面的组状态中是我所追求的。谢谢

Group  Row Status  Group Status
A      Good        Good
B      Good        Neutral
B      Neutral     Neutral
B      Bad         Neutral
C      Bad         Bad
D      Good        Error
D      Bad         Error
D      Error       Error

我上面的表格中有一个错误,Good+Neutral+Bad=Bad 和 C 应该是 Neutral=Neutral,所以这会导致与 @forpas 和 @Gordon Linoff 的答案有些混淆
我在下面添加了另一个表格以更好地显示案例/规则
任何带有错误 = 错误的混合
好的 中性 坏 = 坏
的任何组合 任何不同的状态 = 那个状态

Group   Row Status  Group Status
A       Good        Bad
A       Bad         Bad
A       Neutral     Bad
B       Good        Bad
B       Bad         Bad
C       Good        Bad
C       Neutral     Bad
D       Bad         Bad
D       Neutral     Bad
E       Good        Good
F       Bad         Bad
G       Neutral     Neutral
H       Error       Error
I       Good        Error
I       Bad         Error
I       Neutral     Error
I       Error       Error
J       Good        Error
J       Bad         Error
J       Error       Error
K       Good        Error
K       Neutral     Error
K       Error       Error
L       Bad         Error
L       Neutral     Error
L       Error       Error
M       Good        Error
M       Error       Error
N       Bad         Error
N       Error       Error
O       Neutral     Error
O       Error       Error

我能够使用@forpas 方法获得我想要的结果。我认为这应该涵盖我所有的情况。

with cte as (
  select
    [Group],
    sum(case [Row Status] when 'Good' then 1 else 0 end) good,
    sum(case [Row Status] when 'Neutral' then 1 else 0 end) neutral,
    sum(case [Row Status] when 'Bad' then 1 else 0 end) bad,
    sum(case [Row Status] when 'Error' then 1 else 0 end) error
  from [Test].[dbo].[GroupStatus]
  group by [Group]
)
select 
  t.*,
  case 
    when c.error > 0 then 'Error'
    when c.good * c.neutral * c.bad > 0 then 'Bad'
    when c.good * c.neutral > 0 then 'Bad'
    when c.bad * c.neutral > 0 then 'Bad'
    when c.good * c.bad > 0 then 'Bad'
    when c.good > 0 then 'Good'
    when c.bad > 0 then 'Bad'
    when c.neutral > 0 then 'Neutral'
    else 'Error'
  end [Group Status] 
from [Test].[dbo].[GroupStatus] t inner join cte c
on c.[Group] = t.[Group]

【问题讨论】:

  • 请解释组状态的规则。不明显。

标签: sql sql-server tsql join case


【解决方案1】:

编辑在新的示例数据和说明之后。
你可以用条件聚合来解决这个问题:

with cte as (
  select
    [Group],
    sum(case [Row Status] when 'Good' then 1 else 0 end) good,
    sum(case [Row Status] when 'Neutral' then 1 else 0 end) neutral,
    sum(case [Row Status] when 'Bad' then 1 else 0 end) bad,
    sum(case [Row Status] when 'Error' then 1 else 0 end) error
  from tablename
  group by [Group]
)
select 
  t.*,
  case 
    when c.error > 0 then 'Error'
    when (c.bad > 0) or (c.good * c.neutral > 0) then 'Bad'
    when c.neutral > 0 then 'Neutral'
    when c.good > 0 then 'Good'
    else 'Error'
  end [Group Status]
from tablename t inner join cte c
on c.[Group] = t.[Group]

请参阅demo
结果:

> Group | Row Status | Group Status
> :---- | :--------- | :-----------
> A     | Good       | Bad         
> A     | Bad        | Bad         
> A     | Neutral    | Bad         
> B     | Good       | Bad         
> B     | Bad        | Bad         
> C     | Good       | Bad         
> C     | Neutral    | Bad         
> D     | Bad        | Bad         
> D     | Neutral    | Bad         
> E     | Good       | Good        
> F     | Bad        | Bad         
> G     | Neutral    | Neutral     
> H     | Error      | Error       
> I     | Good       | Error       
> I     | Bad        | Error       
> I     | Neutral    | Error       
> I     | Error      | Error       
> J     | Good       | Error       
> J     | Bad        | Error       
> J     | Error      | Error       
> K     | Good       | Error       
> K     | Neutral    | Error       
> K     | Error      | Error       
> L     | Bad        | Error       
> L     | Neutral    | Error       
> L     | Error      | Error       
> M     | Good       | Error       
> M     | Error      | Error       
> N     | Bad        | Error       
> N     | Error      | Error       
> O     | Neutral    | Error       
> O     | Error      | Error  

【讨论】:

  • 谢谢@forpas 我没有最好地解释我的问题,但在使用你第一个方法后得到了我的结果。我想我已经涵盖了所有情况。
【解决方案2】:

假设您有一个优先级,例如:

  1. 错误
  2. 中性
  3. 不好

你可以使用窗口函数:

select t.*,
       (case when sum(case when row_status = 'Error' then 1 else 0 end) over (partition by group) > 0
             then 'Error'
             when sum(case when row_status = 'Neutral' then 1 else 0 end) over (partition by group) > 0
             then 'Neutral'
             when sum(case when row_status = 'Bad' then 1 else 0 end) over (partition by group) > 0
             then 'Bad'
             else 'Good'
        end) as group_status             
from t;

编辑:

我认为你修改后的逻辑是:

select t.*,
       (case when min(row_status) over (partition by group) = max(row_status) over (partition by group)
             then min(row_status) over (partition by group)
             when sum(case when row_status = 'Error' then 1 else 0 end) over (partition by group) > 0
             then 'Error'
             else 'Bad'
        end) as group_status             
from t;

【讨论】:

  • 嗨@Gordon Linoff 我没有很好地解释我原来的问题的规则,但更新了我的问题
  • 你的 sql 没有运气dbfiddle.uk/…
  • @TBP 。 . . SQL Fiddle 真的很有帮助。我修复了查询。
  • 嗨@Gordon Linoff 你能在dbfiddle.uk 上再次修复查询并将更新后的网址发送给我吗? forpas 方法对我有用,但也想看看你的方法。
猜你喜欢
  • 2017-11-27
  • 2019-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-12
  • 2017-06-17
  • 2021-11-12
  • 2021-08-15
相关资源
最近更新 更多