SpousesTable SpouseID
SpousePreviousAddressesTable PreviousAddressID , SpouseID ,FromDate,AddressTypeID
我现在所拥有的是更新整个表格的最新版本并分配最新版本而不管SpouseID的AddressTypeID = 1
我想分配最新的SpousePreviousAddress.AddressTypeID = 1 对于SpousePreviousAddresses表中的每个唯一SpouseID。
UPDATE spa
SET spa.AddressTypeID = 1
FROM SpousePreviousAddresses AS spa INNER JOIN Spouses ON spa.SpouseID = Spouses.SpouseID,
(SELECT TOP 1 SpousePreviousAddresses.* FROM SpousePreviousAddresses
INNER JOIN Spouses AS s ON SpousePreviousAddresses.SpouseID = s.SpouseID
WHERE SpousePreviousAddresses.CountryID = 181 ORDER BY SpousePreviousAddresses.FromDate DESC) as us
WHERE spa.PreviousAddressID = us.PreviousAddressID
我想我需要一个小组,但我的sql并不是那么热门。感谢。
正在运行的更新
我之前找到了解决方案的错误。以下是我要使用的解决方案
WITH result AS
(
SELECT ROW_NUMBER() OVER (PARTITION BY SpouseID ORDER BY FromDate DESC) AS rowNumber, *
FROM SpousePreviousAddresses
WHERE CountryID = 181
)
UPDATE result
SET AddressTypeID = 1
FROM result WHERE rowNumber = 1
答案 0 :(得分:5)
假设您正在使用SQLServer 2005(基于您从上一次尝试中获得的错误消息),可能最直接的方法是将ROW_NUMBER()函数与公用表表达式一起使用,我想这可能是做你想要的:
WITH result AS
(
SELECT
ROW_NUMBER() OVER (PARTITION BY SpouseID ORDER BY FromDate DESC) as rowNumber,
*
FROM
SpousePreviousAddresses
)
UPDATE SpousePreviousAddresses
SET
AddressTypeID = 2
FROM
SpousePreviousAddresses spa
INNER JOIN result r ON spa.SpouseId = r.SpouseId
WHERE r.rowNumber = 1
AND spa.PreviousAddressID = r.PreviousAddressID
AND spa.CountryID = 181
在SQLServer2005中,ROW_NUMBER()函数是最强大的函数之一。它在很多情况下非常有用。学习它的时间将多次重新支付。
CTE用于简化代码abit,因为它不需要某种临时表来存储itermediate结果。
生成的查询应该快速有效。我知道CTE中的select使用*,这有点过分,因为我们不需要所有列,但如果有人想看看查询中发生了什么,它可能有助于显示正在发生的事情。
答案 1 :(得分:1)
这是一种方法:
UPDATE spa1
SET spa1.AddressTypeID = 1
FROM SpousePreviousAddresses AS spa1
LEFT OUTER JOIN SpousePreviousAddresses AS spa2
ON (spa1.SpouseID = spa2.SpouseID AND spa1.FromDate < spa2.FromDate)
WHERE spa1.CountryID = 181 AND spa2.SpouseID IS NULL;
换句话说,更新行spa1
,其中没有其他行spa2
存在同一配偶和更大(更近期)的日期。
SpouseID
的每个值只有一行,与具有相同SpouseID
的所有其他行(如果有)相比,日期最长。
不需要使用GROUP BY
,因为连接完成了一种隐式分组。
更新:我认为您误解了OUTER JOIN
的目的。如果没有匹配所有连接条件的行spa2
,则spa2.*
的所有列都将返回为NULL。这就是外连接的工作方式。因此,您可以通过测试spa1
来搜索spa2
没有匹配行spa2.SpouseID IS NULL
的情况。
答案 2 :(得分:0)
UPDATE spa SET spa.AddressTypeID = 1
WHERE spa.SpouseID IN (
SELECT DISTINCT s1.SpouseID FROM Spa S1, SpousePreviousAddresses S2
WHERE s1.SpouseID = s2.SpouseID
AND s2.CountryID = 181
AND s1.PreviousAddressId = s2.PreviousAddressId
ORDER BY S2.FromDate DESC)
只是一个猜测。