将重复数据从最后一行更新到第一行

时间:2015-11-14 05:27:52

标签: sql sql-server tsql

表名:客户

| CID | First | Last | RandomNumber |
|  1  |   J   |  T   |     432      |
|  2  |   J   |  T   |     432      |
|  3  |   J   |  T   |     432      |
|  4  |   J   |  T   |     100      |
|  5  |   S   |  A   |     432      |
|  6  |   S   |  A   |     432      |
|  7  |   S   |  A   |     200      |

我有一个大约500行的表,我想用最后一个重复行中的数据更新第一个重复行。最后,第一行的随机数应为100.我希望能够对表中的任何重复项执行此操作。

谢谢。

2 个答案:

答案 0 :(得分:0)

这样的事情应该这样做。我假设重复,你的意思是第一个,最后一个的组合。首先创建一个cte,对重复项中的每一行进行排名,以便您知道哪个是第一行,哪个是最后一行。然后使用cte将第一行连接到最后一行并更新。

我会测试这只是为了确保。我是根据你的样本数据做的,但它确实有用。

;with cte AS
(
SELECT 
    *
    , ROW_NUMBER() OVER (PARTITION BY FIRST, LAST ORDER BY CID) AS Rnk
FROM Customers
)

-- This will show you what will be updated
SELECT cte1.cid, cte1.first, cte1.last, cte1.RandomNumber, cte2.RandomNumber
FROM cte cte1
JOIN (SELECT first, last, max(rnk) as MaxRnk FROM cte GROUP BY first, last) a 
ON a.first = cte1.first and a.last = cte1.last and cte1.rnk = 1
JOIN cte cte2 on cte1.first = cte2.first and cte1.last = cte2.last and cte2.rnk = a.maxrnk


-- The update
UPDATE cte1
SET cte1.RandomNumber = cte2.RandomNumber
FROM cte cte1
JOIN (SELECT first, last, max(rnk) as MaxRnk FROM cte GROUP BY first, last) a 
ON a.first = cte1.first and a.last = cte1.last and cte1.rnk = 1
JOIN cte cte2 on cte1.first = cte2.first and cte1.last = cte2.last and cte2.rnk = a.maxrnk

答案 1 :(得分:0)

在SQL Server 2012+中,您可以使用FIRST_VALUE()

with toupdate as (
      select c.*,
             first_value(randomnumber) over (partition by first, last order by id desc) as last_randomnumber
      from customer c
     )
update toupdate
    set randomnumber = last_randomnumber
    where randomnumber <> last_randomnumber;

如果随机数可以取where个值,则逻辑(在NULL中)稍微复杂一些。

在早期版本中,您可以使用outer apply执行基本相同的操作:

with toupdate as (
      select c.*, clast.randomnumber as last_randomnumber
      from customer c outer apply
           (select top 1 c2.*
            from customer c2
            where c2.first = c.first and c2.last = c.last 
            order by id desc
           ) clast
     )
update toupdate
    set randomnumber = last_randomnumber
    where randomnumber <> last_randomnumber;