当相同 table 的另一列的多个记录匹配时更新列
update a column when multiple records of another columns of same table matches
我有 table 如下:
Input table:
RequestNumber TrackName Date
-----------------------------------------------------------
02209 Middle 2017-05-28 00:00:00
0263 Middle 2017-06-29 00:00:00
0633 Middle 2017-09-10 00:00:00
0762 Back 2017-06-23 00:00:00
0762 Front 2017-06-23 00:00:00
0762 Middle 2017-06-23 00:00:00
01839 Middle 2017-03-09 00:00:00
我需要检查 "RequestNumber" 和 "Date" 是否与 "TrackName" 相同。
如果 "RequestNumber" 和 "Date" 的多个记录匹配,那么我应该将 "TrackName" 列更新为 "All three" 如下
输出示例(本例中有3条记录匹配)
Output table:
RequestNumber TrackName Date
-----------------------------------------------------------
02209 Middle 2017-05-28 00:00:00
0263 Middle 2017-06-29 00:00:00
0633 Middle 2017-09-10 00:00:00
0762 All three 2017-06-23 00:00:00
01839 Middle 2017-03-09 00:00:00
要获得上述期望的输出,这是我尝试过的SQL。然而,它将所有 TrackName 更新为全部三个。
UPDATE a
SET a.[TrackName] = 'All three'
FROM Table1 as a
INNER JOIN
(SELECT [RequestNumber], row_number() OVER (ORDER BY [RequestNumber] DESC) as rowNumber
FROM Table1 ) drRowNumbers ON drRowNumbers.[RequestNumber] = a.[RequestNumber] and drRowNumbers.[Date] = a.[Date]
希望我已经正确解释了这一点。我在做什么?请问有什么问题可以解决吗?
注意:记录是动态的,因此不能硬编码(如果有的话)。
谢谢。
我想你想要SELECT
声明:
SELECT t1.RequestNumber, (CASE WHEN COUNT(DISTINCT t1.TrackName) = t2.TrackNo
THEN CONCAT('All ', t2.TrackNo)
ELSE MIN(t1.TrackName)
END) AS TrackName, t1.Date
FROM table1 t1 CROSS JOIN
(SELECT COUNT(DISTINCT TrackName) AS TrackNo FROM table1) AS t2
GROUP BY t1.RequestNumber, t1.Date;
试试这个。这将 return "All 3" 而不是 "All Three"-
SELECT RequestNumber,
CASE
WHEN COUNT(*) = 1 THEN MAX(TrackName)
ELSE 'All ' + CAST( COUNT(*) AS VARCHAR)
END TrackName,
Date
FROM your_table
GROUP BY RequestNumber,Date
这不仅是更新,也是删除。
这意味着您必须有一个两步过程 - 一个是更新相关记录,另一个是删除第一步创建的重复项。
这可以通过使用 window 函数(例如 count() over()
和 row_number() over()
)的几个常见 table 表达式来完成,当这两个步骤都在事务中加入时.
首先,创建并填充示例 table(请在您以后的问题中为我们省去这一步):
DECLARE @T AS TABLE
(
RequestNumber int,
TrackName varchar(10),
[Date] datetime2
);
INSERT INTO @T (RequestNumber, TrackName, Date) VALUES
(02209, 'Middle', '2017-05-28 00:00:00'),
(0263, 'Middle', '2017-06-29 00:00:00'),
(0633, 'Middle', '2017-09-10 00:00:00'),
(0762, 'Back', '2017-06-23 00:00:00'),
(0762, 'Front', '2017-06-23 00:00:00'),
(0762, 'Middle', '2017-06-23 00:00:00'),
(01839, 'Middle', '2017-03-09 00:00:00');
接下来,启动一个 try
区块和一个交易:
BEGIN TRY
BEGIN TRANSACTION;
然后,识别并更新相关记录:
WITH CTE AS
(
SELECT RequestNumber,
TrackName,
Date,
COUNT(TrackName) OVER(PARTITION BY RequestNumber, Date) As Cnt
FROM @T
)
UPDATE CTE
SET TrackName = 'All Three'
WHERE Cnt = 3;
接下来,删除重复项:
WITH CTE AS
(
SELECT RequestNumber,
TrackName,
Date,
ROW_NUMBER() OVER(PARTITION BY RequestNumber, Date ORDER BY TrackName) As Rn
FROM @T
)
DELETE
FROM CTE
WHERE Rn > 1;
提交交易并关闭 try
区块:
COMMIT TRANSACTION;
END TRY
使用 catch 块回滚事务:
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION
-- you might want to print the result of ERROR_MESSAGE() here...
END CATCH
最后,select 查看更改:
SELECT RequestNumber,
TrackName,
Date
FROM @T
结果:
RequestNumber TrackName Date
2209 Middle 28.05.2017 00:00:00
263 Middle 29.06.2017 00:00:00
633 Middle 10.09.2017 00:00:00
762 All Three 23.06.2017 00:00:00
1839 Middle 09.03.2017 00:00:00
You can see a live demo on rextester(减去那里不允许的事务部分和 try...catch,无论如何没有事务就不相关)
试试这个
第 1 步将其中一个记录设置为全部三个
update table1
set TrackName = 'All Three'
where requestnumber in (select requestnumber
from table1
group by requestnumber,[date]
having count(*) = 3)
and trackname = 'Front'
第 2 步删除不再需要的数据
delete table1
where requestnumber in (select requestnumber
from table1
group by requestnumber,[date]
having count(*) = 3)
and trackname <> 'All Three'
我有 table 如下:
Input table:
RequestNumber TrackName Date
-----------------------------------------------------------
02209 Middle 2017-05-28 00:00:00
0263 Middle 2017-06-29 00:00:00
0633 Middle 2017-09-10 00:00:00
0762 Back 2017-06-23 00:00:00
0762 Front 2017-06-23 00:00:00
0762 Middle 2017-06-23 00:00:00
01839 Middle 2017-03-09 00:00:00
我需要检查 "RequestNumber" 和 "Date" 是否与 "TrackName" 相同。 如果 "RequestNumber" 和 "Date" 的多个记录匹配,那么我应该将 "TrackName" 列更新为 "All three" 如下 输出示例(本例中有3条记录匹配)
Output table:
RequestNumber TrackName Date
-----------------------------------------------------------
02209 Middle 2017-05-28 00:00:00
0263 Middle 2017-06-29 00:00:00
0633 Middle 2017-09-10 00:00:00
0762 All three 2017-06-23 00:00:00
01839 Middle 2017-03-09 00:00:00
要获得上述期望的输出,这是我尝试过的SQL。然而,它将所有 TrackName 更新为全部三个。
UPDATE a
SET a.[TrackName] = 'All three'
FROM Table1 as a
INNER JOIN
(SELECT [RequestNumber], row_number() OVER (ORDER BY [RequestNumber] DESC) as rowNumber
FROM Table1 ) drRowNumbers ON drRowNumbers.[RequestNumber] = a.[RequestNumber] and drRowNumbers.[Date] = a.[Date]
希望我已经正确解释了这一点。我在做什么?请问有什么问题可以解决吗?
注意:记录是动态的,因此不能硬编码(如果有的话)。
谢谢。
我想你想要SELECT
声明:
SELECT t1.RequestNumber, (CASE WHEN COUNT(DISTINCT t1.TrackName) = t2.TrackNo
THEN CONCAT('All ', t2.TrackNo)
ELSE MIN(t1.TrackName)
END) AS TrackName, t1.Date
FROM table1 t1 CROSS JOIN
(SELECT COUNT(DISTINCT TrackName) AS TrackNo FROM table1) AS t2
GROUP BY t1.RequestNumber, t1.Date;
试试这个。这将 return "All 3" 而不是 "All Three"-
SELECT RequestNumber,
CASE
WHEN COUNT(*) = 1 THEN MAX(TrackName)
ELSE 'All ' + CAST( COUNT(*) AS VARCHAR)
END TrackName,
Date
FROM your_table
GROUP BY RequestNumber,Date
这不仅是更新,也是删除。
这意味着您必须有一个两步过程 - 一个是更新相关记录,另一个是删除第一步创建的重复项。
这可以通过使用 window 函数(例如 count() over()
和 row_number() over()
)的几个常见 table 表达式来完成,当这两个步骤都在事务中加入时.
首先,创建并填充示例 table(请在您以后的问题中为我们省去这一步):
DECLARE @T AS TABLE
(
RequestNumber int,
TrackName varchar(10),
[Date] datetime2
);
INSERT INTO @T (RequestNumber, TrackName, Date) VALUES
(02209, 'Middle', '2017-05-28 00:00:00'),
(0263, 'Middle', '2017-06-29 00:00:00'),
(0633, 'Middle', '2017-09-10 00:00:00'),
(0762, 'Back', '2017-06-23 00:00:00'),
(0762, 'Front', '2017-06-23 00:00:00'),
(0762, 'Middle', '2017-06-23 00:00:00'),
(01839, 'Middle', '2017-03-09 00:00:00');
接下来,启动一个 try
区块和一个交易:
BEGIN TRY
BEGIN TRANSACTION;
然后,识别并更新相关记录:
WITH CTE AS
(
SELECT RequestNumber,
TrackName,
Date,
COUNT(TrackName) OVER(PARTITION BY RequestNumber, Date) As Cnt
FROM @T
)
UPDATE CTE
SET TrackName = 'All Three'
WHERE Cnt = 3;
接下来,删除重复项:
WITH CTE AS
(
SELECT RequestNumber,
TrackName,
Date,
ROW_NUMBER() OVER(PARTITION BY RequestNumber, Date ORDER BY TrackName) As Rn
FROM @T
)
DELETE
FROM CTE
WHERE Rn > 1;
提交交易并关闭 try
区块:
COMMIT TRANSACTION;
END TRY
使用 catch 块回滚事务:
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION
-- you might want to print the result of ERROR_MESSAGE() here...
END CATCH
最后,select 查看更改:
SELECT RequestNumber,
TrackName,
Date
FROM @T
结果:
RequestNumber TrackName Date
2209 Middle 28.05.2017 00:00:00
263 Middle 29.06.2017 00:00:00
633 Middle 10.09.2017 00:00:00
762 All Three 23.06.2017 00:00:00
1839 Middle 09.03.2017 00:00:00
You can see a live demo on rextester(减去那里不允许的事务部分和 try...catch,无论如何没有事务就不相关)
试试这个
第 1 步将其中一个记录设置为全部三个
update table1
set TrackName = 'All Three'
where requestnumber in (select requestnumber
from table1
group by requestnumber,[date]
having count(*) = 3)
and trackname = 'Front'
第 2 步删除不再需要的数据
delete table1
where requestnumber in (select requestnumber
from table1
group by requestnumber,[date]
having count(*) = 3)
and trackname <> 'All Three'