问题:按优先级顺序选择SQL记录

问题:按优先级顺序选择SQL记录,sql,case,Sql,Case,我有一个SQL Server查询,其中一个地址类型可以有多个位置名称,但我需要根据类型只带一个位置。优先事项是: 如果AddressType=Facility,则返回该LocationName。在下面的记录中,我只会带回奥兰多 LocationName AddressType ID Orlando Facility 123 Phoenix Billing 345 LA Office

我有一个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 only,则位置将为空。在下面的记录中,它将为空:

    Location       AddressType   ID
    Phoenix        Billing      345
我尝试使用案例陈述:

    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\u row\u num:

    select *
    from t
    where addresstype_row_num = (select (min addresstype_row_num)
                                 from t2
                                 where t.id = t2.id)
然而,这花费了太长的时间,并且返回了某种笛卡尔连接。有更好的方法解决这个问题吗?

您可以使用行号:

这个案子可能有点麻烦。一种方法是使用charindex:

注:这对书面设施名称施加了限制。它们不能重叠

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 

-跳过临时表

临时表要求您重新写出所有记录。对于较大的数据集,应避免使用温度信号。你可以使用嵌套的子选择来完成你正在做的事情,这会快得多。你有你建议的例子吗?我现在无法测试我的语法的有效性,但如果我犯了错误,我可以发布一个答案让你检查语法。下面是一个例子。根据您的sql平台的不同,它可能会有所不同,但很可能是相同的。使用单个命令执行所有操作,避免使用临时表会更快。根据你的要求,我不太确定我是否回答了你的要求。但是这种类型的sql针对sql进行了优化。您可能需要仔细阅读代码,以获得所需的确切业务规则。
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;
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