从以下规则中删除表中的记录

时间:2017-08-30 16:41:42

标签: sql sql-server

规则1:如果有多行status ='a'而且在年份中,我们不应删除该年份中的任何行。

规则2:在Yearquarter中,如果有一行status ='a'和type(3,4),并且所有其他行都有不同的状态和类型,我们需要删除所有这些行 和年份应该留下一行状态='a'类型(3,4)

这是表格emp

+-------+-------------+------+--------+
| EMPID | YEARQUARTER | TYPE | STATUS |
+-------+-------------+------+--------+
|   105 |       20021 |    3 |    A   |
|   105 |       20021 |    1 |    B   |
|   106 |       20031 |    3 |    A   |
|   107 |       20101 |    4 |    A   |
|   107 |       20101 |    2 |    B   |
|   107 |       20101 |    2 |    B   |
|   108 |       20111 |    5 |    B   |
|   108 |       20111 |    1 |    B   |
|   108 |       20111 |    4 |    A   |
|   109 |       20131 |    3 |    A   |
|   109 |       20131 |    1 |    A   |
|   109 |       20131 |    2 |    B   |
+-------+-------------+------+--------+

删除后 EMP表应该左下角

输出

+-------+-------------+------+--------+
| EMPID | YEARQUARTER | TYPE | STATUS |
+-------+-------------+------+--------+
|   105 |       20021 |    3 |    A   |
|   106 |       20031 |    3 |    A   |
|   107 |       20101 |    4 |    A   |
|   108 |       20111 |    4 |    A   |
|   109 |       20131 |    3 |    A   |
|   109 |       20131 |    1 |    A   |
|   109 |       20131 |    2 |    B   |
+-------+-------------+------+--------+

我正在尝试使用

但是它给出了错误而没有显示出期望的结果

DELETE e1
Emp e1
WHERE 
      E1.[type] IN (3,4)     
  AND  EXISTS (
                SELECT 
                    *
                FROM
                    Emp e2
                WHERE 
                        e1.EMPID = e2.EMPID
                    AND e1.yearquarter = e2.yearquarter
                    AND e2.[status] = 'A'
               )

2 个答案:

答案 0 :(得分:0)

--  Set up the sample data:
    DECLARE @table TABLE(EmpID INT, YearQuarter INT, [Type] INT, [Status] CHAR(1))
    INSERT INTO @table
            ( EmpID, YearQuarter, [Type], [Status] )
    VALUES  
        (105,20021,3,'A'),
        (105,20021,1,'B'),
        (106,20031,3,'A'),
        (107,20101,4,'A'),
        (107,20101,2,'B'),
        (107,20101,2,'B'),
        (108,20111,5,'B'),
        (108,20111,1,'B'),
        (108,20111,4,'A'),
        (109,20131,3,'A'),
        (109,20131,1,'A'),
        (109,20131,2,'B')

--  CTE to get counts by status:
    ; WITH ValueList
    AS (
        SELECT t.EmpID
            , t.YearQuarter
            , t.[Type]
            , t.[Status]
            , iRank = ROW_NUMBER() OVER(PARTITION BY YearQuarter ORDER BY Status)
            , StatusACount = (SELECT COUNT(1) FROM @table WHERE YearQuarter =  t.YearQuarter AND Status = 'A')
        FROM @table t

        )
    -- Delete
    DELETE t
    FROM @table t
        INNER JOIN ValueList v
            ON v.YearQuarter = t.YearQuarter
            AND v.[Type] = t.[Type]
    WHERE 
        --  Per rule 1 we need to keep all rows with multiple A's:
        v.StatusACount = 1
        --  Per rule 2, otherwise delete the non-A's:
        AND v.[Status] <> 'A'

    --  Show what's left:
    SELECT EmpID ,
           YearQuarter ,
           [Type] ,
           [Status]
    FROM @table

答案 1 :(得分:0)

您可以为每个规则使用不同的子规则。

declare @temp table (
EMPID    int,
YEARQUARTER   int,
[TYPE] int,
[STATUS] CHAR(1)
)

insert into @temp
select 105, 20021 ,   3 ,'A' union
select 105, 20021 ,   1 ,'B' union
select 106, 20031 ,   3 ,'A' union
select 107, 20101 ,   4 ,'A' union
select 107, 20101 ,   2 ,'B' union
select 107, 20101 ,   2 ,'B' union
select 108, 20111 ,   5 ,'B' union
select 108, 20111 ,   1 ,'B' union
select 108, 20111 ,   4 ,'A' union
select 109, 20131 ,   3 ,'A' union
select 109, 20131 ,   1 ,'A' union
select 109, 20131 ,   2 ,'B' 

delete from @temp 
where YEARQUARTER in (
    select 
        YEARQUARTER 
    from @temp 
    where [STATUS]='A' 
    and type in (3,4) 
    group by YEARQUARTER 
    HAVING COUNT(*) = 1
)
and YEARQUARTER not in (
    select 
        YEARQUARTER 
    from @temp 
    where [STATUS]='A' 
    group by YEARQUARTER 
    HAVING COUNT(*) > 1) 
and ([STATUS]<>'A' 
and type  not in (3,4))

select * from @temp

结果将是:

+-------+-------------+------+--------+
| EMPID | YEARQUARTER | TYPE | STATUS |
+-------+-------------+------+--------+
|   105 |       20021 |    3 |   A    |
|   106 |       20031 |    3 |   A    |
|   107 |       20101 |    4 |   A    |
|   108 |       20111 |    4 |   A    |
|   109 |       20131 |    1 |   A    |
|   109 |       20131 |    2 |   B    |
|   109 |       20131 |    3 |   A    |
+-------+-------------+------+--------+