我有一个用户表。它有UserId,UserName,Email。我有一个地址表它有AddressId,Address,Country,Userid和addressType。一个用户可以拥有家庭或办公室地址(AddressTypes)或两者(他至少有一个地址)。
我需要选择一个有他地址的用户。如果用户有办公地址,则应该是所选地址。如果办公室地址不可用,则返回家庭住址。 以最高性能执行此操作的方法是什么
答案 0 :(得分:3)
尝试
WITH cteBest as (
SELECT users.userID, COALESCE(O.AddrID, H.AddrID) as AddrID
FROM Users LEFT OUTER JOIN Addr as O on users.userID = O.UserID and O.AddrType = 'Office'
LEFT OUTER JOIN Addr as H on users.userID = H.UserID and H.AddrType = 'Home'
) SELECT Users.UserName, Users.Email, Addr.*
FROM cteBest INNER JOIN Addr on Addr.addrID = cteBest.AddrID
INNER JOIN Users on Users.UserID = cteBest.UserID
这假设每个用户至少有一个家庭/办公室,并且没有多个住宅或多个办公室
编辑:此外,如果您需要性能,请确保您的地址表具有UserID的索引。当然,Addr应该有一个用于AddrID,用户应该有一个用于UserID。
答案 1 :(得分:0)
USERS ADRESS
------ ---------
USER_ID ADDRESS_ID
USERNAME ADDRESS
EMAIL COUNTRY
USER_ID
ADDRESS_TYPE
我想我会用分析函数来做到这一点。 row_number()over()例如:
如果address_type O是office并且H是home,当按顺序降序时,O首先出现,ordr值为1。如果没有办公室地址,则首先是家庭地址,值为1.使用ordr = 1过滤值只会给您一个地址,您可以将其与用户表一起加入。
select *
from user u,
(select user_id,
row_number() over(partition by user_id order by address_type desc) as ordr
from address a) ad
where u.user_id = ad.user_id
and ad.ordr= 1