1

SpousesTable SpouseID

SpousePreviousAddressesTable PreviousAddressID, SpouseID, FromDate, AddressTypeID

What I have now is updating the most recent for the whole table and assigning the most recent regardless of SpouseID the AddressTypeID = 1

I want to assign the most recent SpousePreviousAddress.AddressTypeID = 1 for each unique SpouseID in the SpousePreviousAddresses table.

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

I think I need a group by but my sql isn't all that hot. Thanks.

Update that is Working

I was wrong about having found a solution to this earlier. Below is the solution I am going with

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
4

3 に答える 3

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() 関数は最も強力な関数の 1 つです。多くの状況で非常に便利です。それについて学ぶのに費やした時間は、何倍にもなります。

CTE は、コード abit を単純化するために使用されます。これにより、反復結果を格納するための何らかの一時テーブルが不要になるためです。

結果のクエリは、高速かつ効率的である必要があります。CTE の選択で * が使用されていることは知っていますが、すべての列を必要としないため、これは少しやり過ぎですが、クエリ内で何が起こっているかを知りたい場合は、何が起こっているかを示すのに役立つ場合があります。

于 2008-11-14T22:10:42.850 に答える
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同じを持つ他のすべての行 (存在する場合) と比較して最大の日付を持つ の値ごとに正確に 1 つの行がありますSpouseID

GROUP BY結合によって暗黙のグループ化が行われるため 、 a を使用する必要はありません。

更新: の目的を誤解していると思いますOUTER JOINすべての結合条件にspa2一致する行がない場合、のすべての列がNULL として返されます。それが外部結合の仕組みです。したがって、それをテストすることで、一致する行がない場合を検索できます。spa2.*spa1spa2spa2.SpouseID IS NULL

于 2008-11-14T21:52:51.157 に答える
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)

Just a guess.

于 2008-11-14T20:49:27.227 に答える