规则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'
)
答案 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 |
+-------+-------------+------+--------+