根据一列中的值更改组中另一列中的值

时间:2018-09-28 13:56:07

标签: sql sql-server

我是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在containsfailures列中应获得值“ F” 和其他部门一样  例如:-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  

6 个答案:

答案 0 :(得分:5)

您可以对分区使用MIN来执行此操作。之所以可行,是因为您只有两个标记值。如果您的真实数据包含其他值,则可以在MIN函数中使用一个case表达式。

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

答案 1 :(得分:1)

我的朋友有多种方法可以实现

最简单的方法之一就是使用子查询

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,当DP.DEPT为NULL时知道

祝你好运

答案 2 :(得分:1)

这是具有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

答案 3 :(得分: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

答案 4 :(得分: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

答案 5 :(得分:0)

如果您的列Ddeptcontain失败,则只有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”将始终在结果中排​​在首位