Sql server 当同一表中其他列的多条记录匹配时更新列

Sql server 当同一表中其他列的多条记录匹配时更新列,sql-server,sql-server-2017,Sql Server,Sql Server 2017,我的表格如下: Input table: RequestNumber TrackName Date ----------------------------------------------------------- 02209 Middle 2017-05-28 00:00:00 0

我的表格如下:

            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
我需要检查TrackName的RequestNumber和Date是否相同。 如果RequestNumber和Date的多个reacords匹配,那么我应该更新TrackName列,如下所示 输出示例在本示例中,有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。Howveer,它将所有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 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;

试试这个。这将返回全部3,而不是全部3-

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

这不仅仅是一个更新,也是一个删除。 这意味着您必须有两个步骤-一个是更新相关记录,另一个是删除第一步创建的重复项

这可以通过使用两个常用的表表达式来实现,这些表表达式使用窗口函数,例如count over和row_number over,当这两个步骤都在事务内部联接时

首先,创建并填充样本表。请在以后的问题中为我们保存此步骤:

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;
BEGIN CATCH
    IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION

    -- you might want to print the result of ERROR_MESSAGE() here...
END CATCH
然后,确定并更新相关记录:

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块:

使用catch块回滚事务:

BEGIN TRY
BEGIN TRANSACTION;
BEGIN CATCH
    IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION

    -- you might want to print the result of ERROR_MESSAGE() here...
END CATCH
最后,选择以查看更改:

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
减去那里不允许的事务部分和没有事务就不相关的try…catch

步骤1:将其中一个REC设置为所有三个REC

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'

您希望0762的两条记录都保留在TrackName=‘全部三条’的位置吗?或者也要删除第二行?如果示例中显示RequestNumber和Date匹配,则所有记录都将组合在一起,以提供所有三个字符串。因为TrackName只有3个分类,即。中间、后面和前面。这意味着其他两行应该删除,对吗?是的。但是,输出应该如图所示。