onm*_*way 4 sql-server update distinct
如何将SELECT DISTINCT
查询修改为UPDATE DISTINCT
查询?
重要的是它只更新不同的记录,因为有多个记录与每个 [Finance_Project_Number] 相关联(由于 CRUD 操作)。我只想更新一条记录,因为这只会启动验证数据等的不同过程。
如果由于 DISTINCT 导致多条记录折叠为一行,则可以更新其中任何一条记录 - 没关系。
当我运行我的选择查询时,我得到的结果是:6 982:
SELECT DISTINCT
[Finance_Project_Number]
FROM [InterfaceInfor].[dbo].[ProjectMaster]
WHERE
NOT EXISTS
(
SELECT *
FROM [IMS].[dbo].[THEOPTION]
WHERE
[InterfaceInfor].[dbo].[ProjectMaster].[Finance_Project_Number] =
[IMS].[dbo].[THEOPTION].[NAME]
);
Run Code Online (Sandbox Code Playgroud)
这是我将查询转换为查询的尝试DISTINCT UPDATE
,但这会更新 15 353 条记录:
UPDATE [InterfaceInfor].[dbo].[ProjectMaster]
SET
[Processing_Result_Text] = 'UNIQUE',
[Processing_Result] = 0
WHERE
NOT EXISTS
(
SELECT *
FROM [IMS].[dbo].[THEOPTION]
WHERE
[InterfaceInfor].[dbo].[ProjectMaster].[Finance_Project_Number] =
[IMS].[dbo].[THEOPTION].[NAME]
);
Run Code Online (Sandbox Code Playgroud)
要从您可以使用的每个不同组中更新任意一个
WITH T
AS (SELECT ROW_NUMBER() OVER (PARTITION BY [Finance_Project_Number]
ORDER BY (SELECT 0)) AS RN,
[Processing_Result_Text],
[Processing_Result]
FROM [InterfaceInfor].[dbo].[ProjectMaster]
WHERE NOT EXISTS (SELECT *
FROM [IMS].[dbo].[THEOPTION]
WHERE [InterfaceInfor].[dbo].[ProjectMaster].[Finance_Project_Number] = [IMS].[dbo].[THEOPTION].[NAME]))
UPDATE T
SET [Processing_Result_Text] = 'UNIQUE',
[Processing_Result] = 0
WHERE RN = 1;
Run Code Online (Sandbox Code Playgroud)
如果您决定有一些标准来选择要更新的行,毕竟只ORDER BY (SELECT 0)
需要相应地更改相应的内容,以便首先对所需的目标行进行排序 - 例如,ORDER BY DateInserted desc
如果有这样的列,则会按照名为 DateInserted 的列的顺序更新最新的行存在。
这使用公用表表达式(CTE),因为不允许ROW_NUMBER
直接在WHERE
子句中引用排名函数。允许在与可更新视图相同的情况下通过公共表表达式更新数据(基本上,被更新的数据必须能够直接映射回单个基表中的特定项目)。
如果您还不熟悉排名函数,您可能会SELECT
首先发现CTE 中的 -ing 是有益的。
CREATE TABLE #TheOption(NAME VARCHAR(50));
CREATE TABLE #ProjectMaster
(
Finance_Project_Number VARCHAR(10) NOT NULL,
Processing_Result_Text VARCHAR(50) NULL,
Processing_Result INT NULL
);
INSERT INTO #ProjectMaster (Finance_Project_Number, Processing_Result_Text)
VALUES ('A00001', 'A'),
('A00001', 'B'),
('A00001', 'C'),
('B99999', 'D'),
('B99999', 'E'),
('C47474', 'F'),
('C47474', 'G');
INSERT INTO #TheOption (NAME) VALUES('C47474');
WITH T
AS (SELECT ROW_NUMBER() OVER (PARTITION BY Finance_Project_Number
ORDER BY (SELECT 0)) AS RN,
Finance_Project_Number,
Processing_Result_Text,
Processing_Result
FROM #ProjectMaster pm
WHERE NOT EXISTS (SELECT *
FROM #TheOption opt
WHERE pm.Finance_Project_Number =opt.NAME))
SELECT *
FROM T
ORDER BY Finance_Project_Number, RN;
Run Code Online (Sandbox Code Playgroud)
示例结果如下
的C47474
行被滤除,因为它们中的其他表确实存在,以便不符合NOT EXISTS
,剩余的行由分组Finance_Project_Number
,并且每个组内的分配的序列号。
在这种情况下,黄色行将满足RN = 1
条件并进行更新。但是,除非您ORDER BY
在保证唯一的表达式上使用子句,否则无法保证在每个组中确切地分配这些数字。如果没有这个,它甚至可能在同一语句的连续执行之间发生变化。