2013-04-23 88 views
1

我的一個SQL請求有一個真正的阻塞問題。我的問題是以下幾點:我有第一個表(一個臨時表),其中包含一些用戶和他們的名字,地址,電話號碼,... 我有第二張表(一個「真正的」),其中包含有關一些命令。命令與用戶有關,但有點複雜。爲了更清楚,在這裏我表的定義的一個示例:SQL Server 2008 - 根據其他表中的值執行更新

USER 
ID   char(8) 
LastName nvarchar(30) 
FirstName nvarchar(30) 
PostCode nvarchar(10) 
PhoneNumber nvarchar(20) 
HomeAdress nvarchar(20) 

COMMAND 
ID   char(6) 
CMD_FirstName nvarchar(20) 
CMD_LastName nvarchar(20) 
CMD_PostCode nvarchar(10) 
ID_User  char(8) 

這兩個表的邏輯關係,而不是在實踐中...在命令表,字段「ID_User」通常丟失。 我的SQL resquest的目的是通過填充其ID_User字段在所有命令和相應的用戶之間建立關聯。對於ID_User爲空或空的每個命令,我希望通過匹配字段姓氏,名字 和郵政編碼來檢索用戶。如果這種匹配是嚴格的(USER表中沒有雙倍數,這很重要),我可以填充ID_User字段。

你能幫我解決這個大而複雜的問題嗎? 提前,謝謝!

PS:我使用Microsoft SQL Server 2008 R2

回答

4
update c 
set id_user = u.ID 
from [user] u 
join [command] c on c.cmd_firstname = u.firstname 
       and c.cmd_lastname = u.lastname 
       and c.cmd_postcode = u.postcode; 

要排除匹配多個user這名字/姓氏/郵政編碼組合,可以預先彙總的user表和過濾這些的。

update c 
set id_user = u.ID 
from [command] c 
join (select firstname, lastname, postcode, min(ID) ID 
     from [user] 
     group by firstname, lastname, postcode 
     having count(*) = 1) u 
    on c.cmd_firstname = u.firstname 
    and c.cmd_lastname = u.lastname 
    and c.cmd_postcode = u.postcode; 
+1

我想到了這樣的事情,是的。但是這個請求沒有驗證匹配的唯一性...如果我在表USER中有兩個(或更多)用戶具有相同的姓氏,名字和郵政編碼,請求更新COMMAND的ID_User,我不想要... – DaveLeGO 2013-04-23 10:21:14

+0

已更新,以處理重複的問題 – RichardTheKiwi 2013-04-23 10:24:47

+0

我非常喜歡這個解決方案,謝謝。但是我在第二行發生錯誤,因爲JOIN中的SELECT不帶ID,所以我不能在SET中使用u.ID。如果我把這個ID放在SELECT中,我必須把它放在GROUP BY中,我不想... – DaveLeGO 2013-04-23 12:13:56

1

您需要確保,也沒有[用戶],[COMMAND]都不包含您想用於映射它們的字段的重複記錄。 這包含相關查詢,對於大型表格可能不是非常有效。

update [command] 
set ID_User = u.id 
from [USER] u 
join COMMAND c 
    on u.LastName=c.CMD_LastName 
    and u.FirstName = c.CMD_FirstName 
    and u.PostCode = c.CMD_PostCode 
where 1=1 
    and not exists (
     select 
      LastName, FirstName, PostCode 
     from [user] 
     where 1=1 
      and LastName=u.LastName 
      and FirstName=u.FirstName 
      and PostCode=u.PostCode 
     group by 
      LastName, FirstName, PostCode 
     having count(*)>1 
    ) 
    and not exists (
     select 
      CMD_LastName, CMD_FirstName, CMD_PostCode 
     from COMMAND 
     where 1=1 
      and CMD_FirstName=c.CMD_FirstName 
      and CMD_LastName=c.CMD_LastName 
      and CMD_PostCode=c.CMD_PostCode 
     group by 
      CMD_LastName, CMD_FirstName, CMD_PostCode 
     having count(*)>1 
    )