从条件中选择1到多个关系的记录

时间:2014-09-02 16:08:11

标签: database sql-server-2008

我有一个用户表。它有UserId,UserName,Email。我有一个地址表它有AddressId,Address,Country,Userid和addressType。一个用户可以拥有家庭或办公室地址(AddressTypes)或两者(他至少有一个地址)。

我需要选择一个有他地址的用户。如果用户有办公地址,则应该是所选地址。如果办公室地址不可用,则返回家庭住址。 以最高性能执行此操作的方法是什么

2 个答案:

答案 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