我有一个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)
但是,这花了太长时间,并且还返回了一些笛卡尔联盟。有没有更好的方法来解决这个问题?
答案 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
- ##(跳过临时表)