按优先级顺序选择SQL记录

时间:2017-07-17 19:58:26

标签: sql case

我有一个SQL Server查询,其中一个地址类型可以有多个位置名称,但我需要根据类型只带一个位置。优先事项是: 如果AddressType = Facility,则返回该LocationName。在下面的记录中,我只会带回奥兰多。

    LocationName   AddressType  ID
    Orlando        Facility     123
    Phoenix        Billing      345
    LA             Office       678

如果没有AddressType = Facility,但有一个用于Office,则返回该位置。在下面的记录中,它只会带回洛杉矶。

    Location       AddressType    ID
    Phoenix        Billing        345
    LA             Office         678

如果AddressType仅等于Billing,则该位置将为null。在下面的记录中它将为null:

    Location       AddressType   ID
    Phoenix        Billing      345

我尝试使用Case语句:

    select id, location, addresstype,
    CASE when addresstype = 'Facility' then 1
         when addresstype = 'Office' then 2
         when addresstype = 'Billing' then 3 end as addresstype_row_num
         into #test t
         from table

从此我创建了另一个查询来选择最小的addresstype_row_num:

    select *
    from t
    where addresstype_row_num = (select (min addresstype_row_num)
                                 from t2
                                 where t.id = t2.id)

但是,这花了太长时间,并且还返回了一些笛卡尔联盟。有没有更好的方法来解决这个问题?

2 个答案:

答案 0 :(得分:1)

您可以使用row_number()

select id, location, addresstype,
from (select t.*,
             row_number() over (partition by location
                                order by (case when addresstype = 'Facility' then 1
                                               when addresstype = 'Office' then 2
                                               when addresstype = 'Billing' then 3
                                          end)
                               ) as seqnum
      from table t
     ) t
where seqnum = 1;

case可能有点麻烦。围绕它的一种方法是使用charindex()

select id, location, addresstype,
from (select t.*,
             row_number() over (partition by location
                                order by charindex(addresstype, 'Facility,Office,Billing')
                               ) as seqnum
      from table t
     ) t
where seqnum = 1;

注意:这对设施名称施加了限制(如书面所示)。它们不能重叠。

答案 1 :(得分:0)

select id, location, addresstype, min(addresstype_row_num) as addresstype
from 
( 
select id, location, addresstype,
CASE when addresstype = 'Facility' then 1
     when addresstype = 'Office' then 2
     when addresstype = 'Billing' then 3 end as addresstype_row_num
     from table
) x 
group by id, location, addresstype 

- ##(跳过临时表)