3

我正在使用 SQL Server 2008 R2。

我有 3 个表格,数据已标准化,我正在寻找 Bob Dole 的“家庭”和“手机”电话。但是,我只需要获取每种类型的最高序列电话号码。(以下是 Bob Dole 拥有 2 部手机的示例,每部手机的序列号分别为 2 和 3)

PersonPhoneNumber

PersonPhoneNumberId  Person      PhoneNumberId    PhoneNumberTypeId    Sequence
Guid - vvv           Bob Dole    Guid - A         1                    1
Guid - www           Bob Dole    Guid - B         2                    2
Guid - xxx           Bob Dole    Guid - C         2                    3

电话号码

PhoneNumberId   Number
Guid - A        111-111-1111
Guid - B        222-222-2222
Guid - C        333-333-3333

电话号码类型

PhoneNumberTypeId     PhoneNumberType
1                     Home
2                     Cell

我想要的输出是这样的(注意我只返回了第一个单元格编号。):

Person      Home            Cell
Bob Dole    111-111-1111    222-222-2222

我在整理数据时遇到了问题

任何有关查询的帮助都会很棒!

4

2 回答 2

3

您可以使用 arow_number()和带有CASE表达式的聚合函数将数据从行转换为列:

select person,
  max(case when rn = 1 and PhoneNumberType = 'Home' then number end) home,
  max(case when rn = 1 and PhoneNumberType = 'Cell' then number end) cell
from
(
  select ppn.person, pn.number,
    pt.PhoneNumberType,
    row_number() over(partition by ppn.person, ppn.PhoneNumberTypeId
                      order by ppn.sequence) rn
  from PersonPhoneNumber ppn
  inner join PhoneNumber pn
    on ppn.PhoneNumberId = pn.PhoneNumberId
  inner join PhoneNumberType pt
    on ppn.PhoneNumberTypeId = pt.PhoneNumberTypeId
) d
group by person;

请参阅带有演示的 SQL Fiddle

这也可以使用 PIVOT 函数来完成:

select person,
  home, 
  cell
from
(
  select ppn.person, pn.number,
    pt.PhoneNumberType,
    row_number() over(partition by ppn.person, ppn.PhoneNumberTypeId
                      order by ppn.sequence) rn
  from PersonPhoneNumber ppn
  inner join PhoneNumber pn
    on ppn.PhoneNumberId = pn.PhoneNumberId
  inner join PhoneNumberType pt
    on ppn.PhoneNumberTypeId = pt.PhoneNumberTypeId
) d
pivot
(
  max(number)
  for PhoneNumberType in (Home, Cell)
) piv
where rn = 1;

请参阅带有演示的 SQL Fiddle

于 2013-05-07T20:21:42.520 回答
2

这是一个带有子查询的示例,用于获取每个类型的第一个序列号。然后,外部查询使用 CASE 语句创建 Home 和 Cell 列。

SELECT  P.Person
        ,MAX(CASE WHEN P.PhoneNumberTypeId = 1 THEN N.Number ELSE NULL END) AS Home
        ,MAX(CASE WHEN P.PhoneNumberTypeId = 2 THEN N.Number ELSE NULL END) AS Cell
FROM    PersonPhoneNumber P
INNER JOIN
        PhoneNumber N
ON      P.PhoneNumberId = N.PhoneNumberId 
INNER JOIN
        (
        SELECT  Person
                ,PhoneNumberTypeId
                ,MIN(Sequence) AS FIRST_NUM
        FROM    PersonPhoneNumber
        GROUP BY
                Person
                ,PhoneNumberTypeId        
        ) SQ1
ON      P.Person = SQ1.Person
AND     P.PhoneNumberTypeId = SQ1.PhoneNumberTypeId
AND     P.Sequence = SQ1.FIRST_NUM
GROUP BY
        P.PERSON
于 2013-05-07T20:27:28.773 回答