Sql 按id(非主键)分组,具有多种地址类型
我的地址表如下所示:Sql 按id(非主键)分组,具有多种地址类型,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我的地址表如下所示: AddressID Street City AddressTypeID PersonID 1 1st 2ave Edmonton 1 10 2 3st 6ave Edmonton 2 10 3 8st 5ave Edmonton 5 10 4
AddressID Street City AddressTypeID PersonID
1 1st 2ave Edmonton 1 10
2 3st 6ave Edmonton 2 10
3 8st 5ave Edmonton 5 10
4 7st 4ave Edmonton 2 11
5 2st 9ave Edmonton 3 12
6 9st 2ave Edmonton 5 12
AddressID Street City AddressTypeID PersonID
1 1st 2ave Edmonton 1 10
4 7st 4ave Edmonton 2 11
6 9st 2ave Edmonton 5 12
在该表中,personid 10有3种不同类型的地址。
我希望结果是GroupbyPersonid,它的优先级为AddressTypeID1,如果这个人没有AddressTypeID1,那么使用AddressTypeID5
我希望输出如下所示:
AddressID Street City AddressTypeID PersonID
1 1st 2ave Edmonton 1 10
2 3st 6ave Edmonton 2 10
3 8st 5ave Edmonton 5 10
4 7st 4ave Edmonton 2 11
5 2st 9ave Edmonton 3 12
6 9st 2ave Edmonton 5 12
AddressID Street City AddressTypeID PersonID
1 1st 2ave Edmonton 1 10
4 7st 4ave Edmonton 2 11
6 9st 2ave Edmonton 5 12
谢谢你回答我的问题
; with cte as (
select
a.AddressID, a.Street, a.City, a.AddressTypeID, a.PersonID,
row_number() over(
partition by a.PersonID
order by case a.AddressTypeID
when 1 then 1
when 5 then 2
else 3
end
) as rn
from address a
)
select *
from cte
where rn = 1
SELECT AddressTable.* FROM AddressTable INNER JOIN
(SELECT PersonID, MIN(AddressID) as MinAddressID GROUP BY PersonID) AS MinIdTable ON
AddressTable.AddressID = MinIdTable.MinIdTable
差不多
SELECT AddressTable.* FROM AddressTable INNER JOIN
(SELECT PersonID, MIN(AddressID) as MinAddressID GROUP BY PersonID) AS MinIdTable ON
AddressTable.AddressID = MinIdTable.MinIdTable
最简单的方法不是分组,而是使用
行数()
函数:
select a.*
from (select a.*,
row_number() over (partition by personId
order by (case when AddressTypeId = 1 then 1
when AddressTYpeId = 5 then 2
else 3
end)
) as seqnum
from addresses a
) a
where seqnum = 1
请注意,我在
order by
子句中使用了case
语句来指定您的优先级。这不是分组方式,而是使用行数()函数:
select a.*
from (select a.*,
row_number() over (partition by personId
order by (case when AddressTypeId = 1 then 1
when AddressTYpeId = 5 then 2
else 3
end)
) as seqnum
from addresses a
) a
where seqnum = 1
请注意,我在order by
子句中使用了case
语句来指定优先级。首先,通过子查询筛选表以仅包括AddressTypeID为1或5的行。然后选择AddressTypeID最低的一个人(因为您希望1的优先级高于5)
首先,通过子查询过滤表,使其仅包括AddressTypeID为1或5的行。然后选择AddressTypeID最低的一个人(因为您希望1的优先级高于5)
如果将AddressTypeID=1映射到1
,将AddressTypeID=5映射到2
,将AddressTypeID=2映射到NULL
,则这只是最大的每组n个问题的另一个变体。不幸的是,我不知道MSSQL是如何做到这一点的人格11的逻辑是什么?他既没有1分也没有5分。一个人是否可以同时拥有AddressTypeID
2和3而不是1或5?您是否对所有可能的AddressTypeID
值都有特定的优先顺序?如果您将AddressTypeID=1映射到1
,AddressTypeID=5映射到2
,AddressTypeID=2映射到NULL
,这只是最大的n个组问题的另一个变体。不幸的是,我不知道MSSQL是如何做到这一点的人格11的逻辑是什么?他既没有1分也没有5分。一个人是否可以同时拥有AddressTypeID
2和3而不是1或5?您是否对所有可能的AddressTypeID
值都有特定的优先顺序?回退顺序是1,然后是5,再也不是2。回退顺序是1,然后是5,再也不是2。