Reputation: 87
I have a really blocking problem with one of my SQL request. My problem is the following : I have a first table (a temporary table) which contains some users and their names, adresses, phone numbers, ... I have a second table (a "real" one) which contains informations about some commands. A command is related to a user, but it's a bit complicated. For more clarity, here a sample of the definition of my tables :
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)
These two tables are logically related, but not in the practice ... In the COMMAND table, the field "ID_User" is usually missing. The purpose of my SQL resquest is to make an association between all the commands and the corresponding user by filling its ID_User field. For each command which the ID_User is null or empty, I want to retrieve the user by matching the fields last name, first name and post code. If this matching is strict (no doublon in the USER table, it's important),I can fill the ID_User field.
Can you please help me with this big and complicated request ? In advance, thanks !
PS : I'm using Microsoft SQL Server 2008 R2
Upvotes: 1
Views: 87
Reputation: 107696
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;
To exclude firstname/lastname/postcode combinations that match more than one user
, you can pre-aggregate the user
table and filter those out.
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;
Upvotes: 4
Reputation: 13141
You need to assure, that nor [USER], neither [COMMAND] contain duplicate records for the fields that you want to use to map them. This contains correlated queries, and may not be very efficient for large tables.
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
)
Upvotes: 1