我可以检查每个ID号的条件,然后在T-SQL中以新列返回结果

问题描述 投票:1回答:5
ID  Grade   Result
1   A       Good
1   B       Good
1   C       Good
1   D       Good
2   A       Good
2   B       Good
3   B       Bad
3   C       Bad
3   D       Bad
.
.
.

我可以检查每个ID号的条件吗?如果一个ID编号具有A和B,则为好;如果一个ID编号没有A,而具有D,则为差。我需要某种类型的过程或循环来检查所有ID号的条件,并在新列中返回值。我真的只想知道这是否可以在T-SQL中完成?我的桌子上有数百个ID号。

sql-server tsql
5个回答
1
投票

尝试一下:

drop table #tmp
select 1 as ID,  'A' as Grade   into #tmp
union select 1,   'B' 
union select 1,   'C' 
union select 1,   'D' 
union select 2,   'A' 
union select 2,   'B' 
union select 3,   'B' 
union select 3,   'C' 
union select 3,   'D' 

select * from #tmp


select ID, Grade,
case when ID in (select ID from #tmp where Grade in ('A','B') group by ID having count(*)>=2) then 'Good' 
     when ID in (select ID from #tmp where Grade not in ('A')) and ID in (select ID from #tmp where Grade in ('D')) then 'BAD' end as Result
from #tmp

0
投票

您可以使用group by和haveing子句来过滤适当的集合antd合并他的结果uisng联盟

A和B的第一次选择检查,D的第二次检查

select  id, grade, 'Good' Result 
from  my_table m1
INNER JOIN  (
  select id  
  from  my_table  
  where grade in ('A', 'B')
  group by id  
  having count(distict grade )  =  2
) t1 on t1.id = m1.id 
UNION 
select  id, grade, 'Bad'  
from  my_table m2
INNER JOIN  (
   select id  
   from  my_table  
   where grade  IN  ( 'A', 'D')
   group by id  
   having count(distict grade )  =  1
   INNER  JOIN  my_table m2 ON t2.id = m2.id and m2.grade ='D'
) t2 ON t2.id = m2.id

0
投票

这是使用string_agg函数的一种方法。

请注意,只有SQL Server 2017或更高版本支持string_agg函数。

DROP TABLE IF EXISTS TEST
CREATE TABLE TEST (ID INT, GRADE VARCHAR(2))

INSERT INTO TEST VALUES
(1,   'A'),
(1,   'B'),
(1,   'C'),
(1,   'D'),
(2,   'A'),
(2,   'B'),
(3,   'B'),
(3,   'C'),
(3,   'D')

;WITH CTE 
AS
(
SELECT ID, STRING_AGG(GRADE,',') AS GRADE_STRING
FROM TEST
GROUP BY ID
)
SELECT TEST.ID, TEST.GRADE, 
CASE WHEN GRADE_STRING LIKE '%A%B%' THEN 'GOOD'
     WHEN GRADE_STRING LIKE '%D%' AND GRADE_STRING NOT LIKE '%A%' THEN 'BAD'
     END AS RESULTS
FROM CTE
JOIN TEST
ON CTE.ID = TEST.ID

测试结果:

DB<>Fiddle


0
投票

使用聚合和case

select id,
       (case when sum(case when grade not in ('A', 'B') then 1 else 0 end) > 0
             then 'good'
             when sum(case when grade = 'A' then 1 else 0 end) = 0 and
                  sum(case when grade = 'D' then 1 else 0 end) > 0
             then 'bad'
             else 'middling'
        end) as overall
from t
group by id;

请注意,我将您的第一个条件解释为“仅具有'A'和'B'的ID。


0
投票

您可以使用SUM()窗口功能来完成它:

select t.ID, t.Grade,
  case
    when t.hasA > 0 and t.hasB > 0 then 'Good'
    when t.hasA = 0 and t.hasD > 0 then 'Bad'
    -- else ?
  end Result
from (
  select *,
    sum(case when Grade = 'A' then 1 else 0 end) over (partition by ID) hasA,
    sum(case when Grade = 'B' then 1 else 0 end) over (partition by ID) hasB,
    sum(case when Grade = 'D' then 1 else 0 end) over (partition by ID) hasD
  from tablename
) t 
© www.soinside.com 2019 - 2024. All rights reserved.