首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >查找副本并删除其应用条件SQL Server

查找副本并删除其应用条件SQL Server
EN

Stack Overflow用户
提问于 2018-12-03 19:22:58
回答 5查看 87关注 0票数 1

我对Server很陌生,我试图从表中删除副本,但是有一些条件,我对如何将这些条件应用于查询表示怀疑。

我需要从Users表中删除副本,例如:

代码语言:javascript
复制
Id    Code    Name   SysName
-----------------------------
1      D1      N1       
2      D1
3      D1      N1       N-1
4      E2      N2
5      E2      N2
6      E2      N2
7      X3
8      X3               N-3    
9
10
11     Z4      W2       N-4-4
12     Z4      W2       N-44

在上表中:对于D1代码,我希望保留ID=3,它填充了所有列(代码、名称和SysName),并删除ID=1和ID=2

对于E2代码,我希望保留其中的任何一个,并删除两个重复的

对于X3代码,保留具有SysName=N-3的代码

对于ID=9,ID=10 (空代码和所有空的,删除所有)

对于Z4代码,删除ID=11并保留N-44 Sysname

最后一件事,我有一个FK和其他表,所以我认为我需要首先从用户获得所有Id,从第二个依赖表中删除这些Id,最后从用户表中删除这些Id。

你对如何实现这个目标有什么想法吗?我不会假装解决方案,而是一个结构代码或类似的示例/场景,任何建议对我来说都是好的。

编辑:

继续..。我有用户表:

代码语言:javascript
复制
Id    Code    Name   SysName
-----------------------------
1      D1      N1       
2      D1
3      D1      N1       N-1
4      E2      N2
5      E2      N2
6      E2      N2
7      X3
8      X3               N-3    
9
10
11     Z4      W2       N-4-4
12     Z4      W2       N-44

我只想保持:

代码语言:javascript
复制
Id    Code    Name   SysName
-----------------------------
3      D1      N1       N-1
4      E2      N2
8      X3               N-3    
12     Z4      W2       N-44
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2018-12-03 20:34:29

你是在找像

代码语言:javascript
复制
SELECT Code,
       MAX(ISNULL(Name, '')) Name,
       MAX(ISNULL(SysName, '')) SysName
FROM T
WHERE Code IS NOT NULL
GROUP BY Code;

返回:

代码语言:javascript
复制
+------+------+---------+
| Code | Name | SysName |
+------+------+---------+
| D1   | N1   | N-1     |
| E2   | N2   |         |
| X3   |      | N-3     |
| Z4   | W2   | N-4-4   |
+------+------+---------+

演示

票数 2
EN

Stack Overflow用户

发布于 2018-12-03 20:44:52

下一个查询显示要根据下一个重要规则删除的ids列表:

1-如果用户拥有所有字段,则将删除空/空字段。

2-具有更多错误字段的用户将首先考虑删除(例如,SysName不能包含两个字段-)。

3-有更多字段为空/空的用户将首先考虑删除。

代码语言:javascript
复制
;WITH
[Ids]
AS
(
    SELECT
         [U].[Id]
        ,[Importance] =
            CASE
                WHEN [X].[NumberOfFilledFields] = 0
                    THEN -1
                ELSE ROW_NUMBER() OVER (PARTITION BY [U].[Code] ORDER BY [X].[NumberOfInvalidFields], [X].[NumberOfFilledFields] DESC)
            END
    FROM [Users] AS [U]
    CROSS APPLY
    (
        SELECT
             [NumberOfFilledFields] =
                + CASE WHEN NULLIF([U].[Code], '') IS NULL THEN 0 ELSE 1 END
                + CASE WHEN NULLIF([U].[Name], '') IS NULL THEN 0 ELSE 1 END
                + CASE WHEN NULLIF([U].[SysName], '') IS NULL THEN 0 ELSE 1 END
            ,[NumberOfInvalidFields] =
                + CASE WHEN [U].[SysName] LIKE '%-%-%' THEN 1 ELSE 0 END
    ) AS [X]
)
SELECT
    [Id]
FROM [Ids]
WHERE (1 = 1)
    AND ([Importance] = -1 OR [Importance] > 1);
票数 1
EN

Stack Overflow用户

发布于 2018-12-03 21:06:05

演示

(任何其他答案:您可以随意借用演示程序来测试您的答案或在您的答案中使用它!)不需要重复努力!)

可以使用像row_number()这样的分析函数/窗口函数为我们想要的每条记录分配一行,并保留所有的#1行,除了代码为null的那些.用cte做这件事,然后删除。

我们通过查看拥有最多数据的记录来确定应该保存什么,如果有关联,则使用最早的ID。

代码语言:javascript
复制
With cte as (
SELECT id, code, name, sysname,
row_number() over (partition by code order by (case when name is not null then 1 else 0 end + case when sysname is not null then 1 else 0 end) desc, ID) RN
FROM users)

Delete from cte where RN <> 1 or code is null;

在以下方面的成果:

代码语言:javascript
复制
+----+----+------+------+---------+
|    | ID | Code | Name | Sysname |
+----+----+------+------+---------+
|  1 |  3 | D1   | N1   | N-1     |
|  2 |  4 | E2   | N2   | NULL    |
|  3 |  8 | X3   | NULL | N-3     |
|  4 | 11 | Z4   | W2   | N-4-4   |
+----+----+------+------+---------+

您可以使用CTE和删除将被清除的相关FK记录,然后再次使用cte并删除用户。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53600503

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档