SQL:删除记录取决于两个变量条件

时间:2019-12-16 15:34:23

标签: sql sql-server sql-delete

取决于以下内容:

Rank  Provincecode provincekey   Name   Value  
 1         ABC        100       address  Detriot
 1         ABC        100        city     NULL
 1         ABC        100        country  US
 1         ABC        100         region   US
 5         ABC        200        address   NULL
 5         ABC        200          city    NULL
 5         ABC        200         Region   NULL
 5         ABC         200        country  NULL   
 9         XYZ         500        address  Texas
 9         XYZ         500        city      TX
 9         xyz         500         country  US
 9         XYZ         500         Region   US

要求是删除按倾斜分组的记录 有以下两个条件:

  • 该群组的排名最低
  • 该组的记录之一的Value列不为空

*如果第二个条件没有通过,我们尝试使用第二低的排名,并检查value值是否包含任何非空值。等等*

无论块值是否为null或不为null,都应仅考虑所需的低排名记录。

o / p:

 1         ABC        100       address  Detriot
 1         ABC        100        city     NULL
 1         ABC        100        country  US
 1         ABC        100         region   US

尝试过类似的东西

DELETE CTE FROM  
      (
      SELECT RANK() OVER(Partition BY NAME ORDER BY Rank Asc, Date Desc, key Desc) AS RNK,FName,Name,Value,Code,key,Date
      FROM #TABLE1  SRC WHERE code = 'ABC' AND FName = 'CITY' AND (ISNULL(Value,'') <> '') 
           UNION 
      SELECT RANK() OVER(Partition BY FName ORDER BY Rank Asc, Date Desc, key Desc) AS RNK,FName,Name,Value,Code,key,Date
      FROM #TABLE1  SRC WHERE code = 'ABC' AND FName = 'CITY' AND (ISNULL(Value,'') = '')   
     ) CTE

     WHERE ((RNK > 1 AND FName = 'ABC' AND (ISNULL(Value,'') <> '')) OR (FName = 'CITY' AND (ISNULL(Value,'') = '')))

这是一个错误。谁能为此提供帮助。

2 个答案:

答案 0 :(得分:1)

我认为您在问题中的逻辑过于复杂。

如果无论值null的状态如何都需要删除它们,则只需使用where并排除空条件即可。

delete from [source table]
where rank > 1

数据存在(不是null)或不是(null),如果您的条件无关紧要,为什么还要完全包含逻辑?

答案 1 :(得分:0)

获得排名似乎是解决这个难题的关键。

以下示例将优先级分配给具有国家/地区的组。

因此,如果只有1个群组,并且该群组没有国家/地区,则不会将其删除。
如果有更多的组,则将保留具有国家/地区的最新组。

样本数据:

CREATE TABLE Table1 
(
  ProvinceCode varchar(3) not null, 
  ProvinceKey int not null, 
  Name nvarchar(30) not null, 
  [Value] nvarchar(30),
  ModifiedDate datetime not null
);

INSERT INTO Table1
(ProvinceCode, ProvinceKey, Name, [Value], ModifiedDate) VALUES 

 ('ABC', 200, 'address', NULL, '2019-12-21')
,('ABC', 200, 'city', NULL, '2019-12-21')
,('ABC', 200, 'region', NULL, '2019-12-21')
,('ABC', 200, 'country', NULL, '2019-12-21')

,('ABC', 100, 'address', 'Detriot', '2019-12-15')
,('ABC', 100, 'city', NULL, '2019-12-15')
,('ABC', 100, 'country', 'US', '2019-12-15')
,('ABC', 100, 'region', 'US', '2019-12-15')

,('XYZ', 500, 'address', 'Texas', '2019-12-09')
,('XYZ', 500, 'city', 'TX', '2019-12-09')
,('XYZ', 500, 'country', 'US', '2019-12-09')
,('XYZ', 500, 'region', 'US', '2019-12-09')

删除:

WITH CTE_SLC1 AS
(
  SELECT *
  , CAST(MAX(CASE WHEN Name = 'country' AND [Value] IS NOT NULL THEN 1 ELSE 0 END) OVER (PARTITION BY ProvinceCode, ProvinceKey) AS BIT) AS hasCountry 
  , MAX(ModifiedDate) OVER (PARTITION BY ProvinceCode, ProvinceKey) AS p_date
  FROM Table1
)
, CTE_SLC2 AS
(
  SELECT *
  , DENSE_RANK() OVER (ORDER BY 1-hasCountry, p_date DESC) AS p_rank
  FROM CTE_SLC1
)
DELETE
FROM CTE_SLC2
WHERE p_rank > 1;

还有什么

SELECT *
FROM Table1
ORDER BY ProvinceCode, ProvinceKey, Name;
GO
ProvinceCode | ProvinceKey | Name    | Value   | ModifiedDate       
:----------- | ----------: | :------ | :------ | :------------------
ABC          |         100 | address | Detriot | 15/12/2019 00:00:00
ABC          |         100 | city    | null    | 15/12/2019 00:00:00
ABC          |         100 | country | US      | 15/12/2019 00:00:00
ABC          |         100 | region  | US      | 15/12/2019 00:00:00

db <>提琴here