选择两列时,删除查询不起作用

delete query is not working when both columns are selected

create table demo11 (dn int, rn varchar(max))
insert into demo11 values(1,'A'),(1,'A-1'),(1,'A-3'),(2,'A'),(2,'B'),(2,'C'),(3,'A-3'),(3,'A-4')
dn rn
1 A
1 A-1
1 A-3
2 A
2 B
2 C
3 A-3
3 A-4

预期结果:

dn rn
1 A-3
2 C
3 A-4

尝试了以下查询但没有成功:

delete from demo11 
where DN NOT in (1,2,3) AND RN NOT IN ('A-3','C','A-4') 

我认为你不需要删除,只需 select 使用 window 函数 例如 ROW_NUMBER()

SELECT dn, rn
  FROM
  (
   SELECT ROW_NUMBER() OVER (PARTITION BY dn ORDER BY rn DESC) AS rnum,
          d.* 
     FROM demo11 AS d 
  ) AS dd
 WHERE rnum = 1 

如果你坚持要删除那些值,那么再次使用window函数例如

WITH t AS
(
 SELECT dn AS dn2, rn AS rn2
   FROM
   (
    SELECT ROW_NUMBER() OVER (PARTITION BY dn ORDER BY rn DESC) AS rnum,
           d.* 
      FROM demo11 AS d 
   ) AS dd
  WHERE rnum > 1 
)
DELETE 
  FROM demo11
 WHERE EXISTS ( SELECT 1 FROM t WHERE rn=rn2 AND dn=dn2)

Demo

首先,定义您要保留的记录, 例如每个 DN 的最大 RN

SELECT dn, max(rn) rn_max from demo11 group by dn

然后,从删除中排除这些记录:

DELETE FROM demo11 d   
    LEFT JOIN ( SELECT dn, max(rn) rn_max from demo11 group by dn ) tmp
    ON d.dn = tmp.dn AND d.rn = tmp.rn_max
    WHERE tmp.dn is null

Tried with following query but not worked:

   delete from demo11 
   where DN NOT in (1,2,3) AND RN NOT IN ('A-3','C','A-4') 

它不是那样工作的,即使只是在基本的数据集方面也是如此。这是一个更简单的例子:

John, Chicago
John, New York
Jane, Chicago

我想要不是来自芝加哥的 John 的所有行。这意味着我想要 John/NewYork 和 Jane/Chicago.

如果我说name <> 'John' and city <> 'Chicago'我排除一切。 Jane 将被保留,因为她的名字不是 John,但她的城市是芝加哥,这不是“不是芝加哥”。这与说 name NOT IN ('John') and city NOT IN ('Chicago') 相同 - 这里的核心问题是您试图将“John from Chicago”排除为一对值,但是这两个子句 (1: name <> 'John', 2: city <> 'Chicago') 不一起工作 - 不把值放在一起。有些行被排除是因为它们是 John,其他行被排除是因为它们是 Chicago - 没有任何值对 John+Chicago 和这个

的概念

真正想要的是NOT(name = 'John' AND city = 'Chicago')。在此,数据保持配对。 John/Chicago 作为子句放在一起,NOT 对它们进行运算。这与某些行因一件事而被排除而其他行因另一件事而被排除

有很大不同

一些数据库允许在 NOT IN 中使用多个值,因此它们也允许这样的结构:

(name, city) NOT IN ('John, 'Chicago')

John/Chicago 的配对再次保持在一起并协同工作以排除值是 John/Chicago 作为一对

的一行

其他答案已经给了你需要使用的SQL,但我想谈谈为什么你的尝试不起作用。您需要了解,您的两个真值语句 DN NOT in (1,2,3)NOT IN ('A-3','C','A-4') 单独工作并影响不同的行。根本没有任何东西可以使两个 IN 中的值配对在一起。如果您的数据库有:

(DN, RN) NOT IN ( (1,'A-3'), (2,'C'), (3,'A-4') )

那么它就可以解决了,因为那些 DN/RN 对是放在一起的。如果你没有像那样工作的数据库,那么你必须使用更像的东西:

NOT (
  (DN=1 AND RN='A-3') OR (DN=2 AND RN='C') OR (DN=3 AND RN='A-4')
)

这些也会将您要查找的数据对“放在一起”,因为它是 this and thatthis2 and that2this3 and that3(不是)