SQL Server中具有动态行数的行到列

时间:2018-08-08 17:50:47

标签: sql sql-server

我的源数据看起来像这样

ID        Phone Type     Phone Number                                                                                                                                                                    
-------------------------------------
308820        P           8136542273
308820        F           8136541384
308820        P           8139108555
308820        P           8136842229
308820        F           8139108655
211111        P           6874598695
456788        F           5687659867

在以上数据中,Phone type = P是电话,F是传真。

我需要对数据进行排序,然后只选择一个F型和一个P型电话号码,并按如下所示填充数据

ID         Fax Number    Phone Number
-------------------------------------
308820     8136541384    8136542273
211111                   6874598695
456788     5687659867

有人可以帮助我实现这一目标吗?一个ID可以有n个电话号码和传真号码,但我需要对其进行排序并选择第一个。

4 个答案:

答案 0 :(得分:1)

您可以使用条件聚合:

select id, max(case when phone_type = 'F' then phone_number end) as fax,
       max(case when phone_type = 'P' then phone_number end) as phone
from t
group by id;

答案 1 :(得分:1)

感谢您的回复。我创建的查询如下。我在上面的查询中使用了上面得到的帮助。但是,问题在于,它在Binary_CheckSum中随机选择一个电话号码,并因此再次选择相同的记录。

我要查找的是,对于特定的ID和AddressID组合,其iSActive标志或电话号码或传真号码已更改,因此我需要选择该记录并将其插入PrescriberLocation表中。

select TESTID, ADDRESSID, max(PhoneNumber) as PhoneNumber,max(FaxNumber) as FaxNumber,'1' as isactive from (select distinct a.TESTID
, b.AddressId , CASE WHEN c.PhoneType = 'P'THEN C.PhoneNumber END PhoneNumber
, CASE WHEN c.PhoneType = 'F'THEN C.PhoneNumber END FaxNumber 
   ,'1' as isactive from stg_Address a inner join stg_AddressPhone c on a.TESTID = c.TESTID and a.AddressID = c.AddressID INNER  join pbmsys_new.dbo.sc_Address b on 
          upper(a.Address1) = upper(b.Address1) and upper(isnull(a.Address2,'')) = upper(b.Address2)  join pbmsys_new.[dbo].[dr_PrescriberLocation] d
          on a.TESTID = d.TESTID and b.AddressId = d.AddressId
          where BINARY_CHECKSUM(1,c.PhoneNumber, FaxNumber) != BINARY_CHECKSUM(d.IsActive,d.PhoneNumber,d.FaxNumber) and d.PrescriberLocationId = SELECT max(Z.PrescriberLocationId) as PrescriberLocationId FROM pbmsys_new.dbo.dr_PrescriberLocation Z where d.TESTID = z.TESTID and d.AddressId =z.AddressId))f group by TESTID, AddressId

答案 2 :(得分:0)

您可以使用聚合函数和子查询

select id,max(fax_Number) as fax_Number, max(phone_Number) as phone_Number
from
(select id, case when phone_type = 'F' then phone_number end as fax_Number,
       case when phone_type = 'P' then phone_number end as phone_Number
from yourtable
) as t group by id

答案 3 :(得分:0)

如果要求选择第一个值而不是最大值,则可以使用它。

; with CTE1
As
(
select row_number() over (partition by id,phonetype order by ID) as Num,ID,
       case when phonetype = 'F' then PhoneNumber end as FaxNumber, 
       case when phonetype = 'P' then PhoneNumber end as PhoneNumber
       from ContactDetails
)
select ID,max(FaxNumber),max(PhoneNumber) 
from (select ID,FaxNumber,PhoneNumber from CTE1 where num = 1)as T2 
group by ID