На основі значення в одному стовпці змінюється значення в іншому стовпці по групі

Я новачок у SQL Server.

У мене є таблиця:

Group   id     DEPT     marks         
--------------------------------------
 A      001      CS      P                  
 A      002     ECE      P  
 A      003     MC       P  
 B      561     CS       F  
 B      781     IT       F  
 C      789     CS       F  
 C      003     CS       F

Якщо департамент має невдачу, у новій колонці департамент містить невдачі, повинні отримати значення 'F'
Тут CS містить F, так що весь dept повинен отримати значення 'F' у колонці deptcontainsfailures де, як і інші відділи
 наприклад: - ECE містить oly P, тому в Ddeptcontainfailures є 'P' Я намагаюся виконати цей вибір

SELECT group,  
      id,  
    dept,  
      marks,  
CASE WHEN marks='P' THEN  'P'   
            ELSE 'F'  
            END Ddeptcontainfailure  
 FROM Depttable

Вихід я отримую


Group   id     DEPT     marks            Ddeptcontainfailures
-----------------------------------------------------
 A      001     CS       P                  p   
 A      002     ECE      P                  P  
 A      003     MC       P                  P  
 B      561     CS       F                  F  
 B      781     IT       F                  F  
 C      789     CS       P                  p  
 C      003     CS       P                  p  

Як це досягти?

Бажаний вихід


Group   id     DEPT     marks      Ddeptcontainfailures
-----------------------------------------------------
 A      001     CS       P          F       
 A      002     ECE      P          P  
 A      003     MC       P          P  
 B      561     CS       F          F  
 B      781     IT       F          F  
 C      789     CS       P          F  
 C      003     CS       P          F  
2

6 Відповіді

Ви можете використовувати MIN з розділенням для цього. Це працює, тому що у вас є лише два значення для позначок. Якщо ваші реальні дані містять інші значення, ви можете використовувати вираз case у функції MIN.

declare @Something table
(
    MyGroup char(1)
    , id char(3)
    , DEPT varchar(3)
    , marks char(1)
)

insert @Something values
('A', '001', 'CS', 'P')
, ('A', '002', 'ECE', 'P')
, ('A', '003', 'MC', 'P')
, ('B', '561', 'CS', 'F')
, ('B', '781', 'IT', 'F')
, ('C', '789', 'CS', 'F')
, ('C', '003', 'CS', 'F')

select s.*
    , min(marks) over(partition by DEPT)
from @Something s
order by s.MyGroup
    , s.id
    , s.DEPT
5
додано
Дякую, це спрацювало
додано Автор PEL1, джерело

Ось ще одне альтернативне рішення зі структурою cte :

create table #temp
(
    MyGroup char(1)
    , id char(3)
    , DEPT varchar(3)
    , marks char(1)
)

insert #temp values
('A', '001', 'CS', 'P')
, ('A', '002', 'ECE', 'P')
, ('A', '003', 'MC', 'P')
, ('B', '561', 'CS', 'F')
, ('B', '781', 'IT', 'F')
, ('C', '789', 'CS', 'F')
, ('C', '003', 'CS', 'F')

;with cte as (
select distinct t.DEPT
from #temp t
where t.marks = 'F'
)
select t.*, (case when t.DEPT in (select DEPT from cte) then 'F' else 'T' end)
from #temp t
0
додано

Альтернатива:

SELECT [group],  
      id,  
    Depttable.dept,  
      marks,  
CASE WHEN isnull(failures, 0) = 0 THEN  'P'   
            ELSE 'F'  
            END Ddeptcontainfailure  
 FROM Depttable
 LEFT OUTER JOIN (
    select count(*) as failures, alias.dept
    from Depttable alias
    where marks='f'
    group by alias.dept
 ) X on x.dept = Depttable.dept
0
додано

Мій друг, є кілька способів зробити це

Одним з найпростіших способів є використання підзапитів

SELECT GROUP
      ,ID
      ,DEPT
      ,MARKS
      ,CASE WHEN DP.DEPT IS NULL THEN 'P' ELSE 'F' END AS DDEPTCONTAINFAILURE
FROM DEPTTABLE DT
LEFT JOIN (SELECT DISTINCT DEPT 
            FROM DEPTTABLE
            WHERE MARKS LIKE 'F') DP 
ON (DT.DEPT = DP.DEPT) 

Якщо ви хочете знати, що департамент має відсутність вартості, ви спочатку повинні знати, який з них. то ви можете використовувати прапор, в моєму випадку я використовую CASE WHEN DP.DEPT НУЛЬКИ знати

Удачі

0
додано
SELECT group,  
      id,  
    dept,  
      marks,  
CASE WHEN 'F' in (select marks from Depttable di where di.marks=do.marks)    THEN  'F'   
            ELSE 'P'  
            END Ddeptcontainfailure  
 FROM Depttable do

або

SELECT group,  
      id,  
    dept,  
      marks,  
(select min(marks) from Depttable di where di.marks=do.marks) Ddeptcontainfailure  
 FROM Depttable do
0
додано

Якщо у вашому стовпці Ddeptcontainfailures є лише 2 значення, можна використовувати цей запит

    declare @temp table(Grou varchar(10), id varchar(10), Dept varchar(10), marks varchar(10))

    insert into @temp (Grou, id, dept, marks)
    select 'A', '001' ,'CS' , 'P'
    union
    select 'A', '002' ,'ECE', 'P'
     union
    select 'A', '003' ,'MC', 'P'
     union
    select 'B', '561' ,'CS', 'F'
     union
    select 'B', '781' ,'IT', 'F'
     union
    select 'C', '789' ,'CS', 'F'
     union
    select 'C', '003' ,'CS', 'F'


    select t.Grou, t.id, t.Dept, t.marks, (select top 1 B.marks from @temp B where B.Dept = t.Dept order by B.marks) as Ddeptcontainfailures

    from @temp t

При сортуванні по B.marks "F" завжди буде першим у результатах

0
додано