如何在T-SQL中将每隔一行转换为列?

时间:2017-12-21 01:16:46

标签: sql sql-server tsql

也许这是一个已被问过的问题。如何将每隔一行转换为T-SQL中的列? 这里有一些T-sql来创建表和示例数据。

CREATE TABLE Names
(
     [ID] int, 
    HouseholdId int,
     [FullName] varchar(max), 
     [ssn] varchar(max),
    isPrimary bit
)
;

INSERT INTO names(ID, HouseholdId, [FullName], ssn, isPrimary)
VALUES
    (1, 10,'User1', '111111111', 1),
    (2, 10, 'User2', '222222222', 0),
    (3, 10, 'User3', '333333333', 0),
    (4, 10, 'User4', '444444444', 0),
    (5, 10,'User5', '555555555', 0),
    (6, 20, 'User6', '666666666', 1),
    (7, 20, 'User7', '777777777', 0)
;

我想将每个家庭用户转换成两列,就像这样。

HouseHold   User Name 1 SSN 1       User Name 2 SSN 2
10          User1       111111111   User2       222222222
            User3       333333333   User4       444444444
            User5       555555555       
20          User6       666666666   User7       777777777

我该怎么做?

2 个答案:

答案 0 :(得分:3)

  

这里的sql将执行您正在寻找的内容。它通过在家庭ID内分区来分配行号。然后使用自联接并排布局。 http://sqlfiddle.com/#!6/c8933/10/0

WITH T AS (
select HouseholdId, ID, Fullname, ssn
  , ROW_NUMBER() OVER(PARTITION BY HouseHoldId Order by ID) AS RNUM
FROM Names
)
SELECT A.HouseholdId, A.fullname as username1, A.SSN as ssn1
, B.fullname as username2, B.ssn as ssn2
FROM T A
LEFT JOIN T B ON A.householdID = B.HouseholdId
  AND (A.RNUM = B.RNUM - 1)
WHERE A.RNUM % 2 = 1 

答案 1 :(得分:0)

这是使用pivot完成相同操作的方法。

select b.HouseholdID
, b.[User Name 1]
, b.[SSN 1]
, b.[User Name 2]
, b.[SSN 2]
from (
    select sub.HouseholdId
    , sub.col_nm_prelim + cast( (((sub.row_nbr + 1) % 2) + 1) as char(1)) as col_nm
    , ceiling(sub.row_nbr / 2.0) as row_nbr
    , sub.col_val
    from (
        select n.HouseholdId
        , 'User Name ' as col_nm_prelim
        , row_number() over (partition by n.HouseHoldID order by n.ID asc) as row_nbr
        , n.FullName as col_val
        from Names as n
        union all
        select n.HouseholdId
        , 'SSN ' as col_nm_prelim
        , row_number() over (partition by n.HouseHoldID order by n.ID asc) as row_nbr
        , n.SSN as col_val
        from Names as n
        ) as sub
    ) as a
pivot (max(a.col_val) for a.col_nm in ([User Name 1], [User Name 2], [SSN 1], [SSN 2])) as b
order by b.HouseholdID asc
, b.row_nbr asc