在SQL Server中将行转换为列

时间:2016-02-05 07:08:14

标签: sql sql-server sql-server-2012

我有一个表user_travel,其中包含以下示例数据:

enter image description here

我希望在每个Visit的{​​{1}}列的帮助下,返回下面显示的输出的查询。

预期输出

user ID

此处id FromD-1visit ToD-1visit FromD-2visit ToD-2visit FromD-3visit ToD-3visit UserID ------------------------------------------------------------------------------------- 1 2017-05-17 2017-05-17 2016-02-02 NULL 2016-02-01 2016-02-09 2 FromDToDFromDate ToDate

我也试过使用(columns),但没有运气。

请帮忙..!

提前致谢...

2 个答案:

答案 0 :(得分:1)

此脚本是动态的。

CREATE TABLE #tt(Id INT,FromDate DATETIME,ToDate DATETIME,Visit INT,UserID INT);
INSERT INTO #tt(Id,FromDate,ToDate,Visit,UserID)VALUES
    (1,'20170517','20170517',1,2),
    (6,'20160202',NULL,2,2),
    (7,'20160201','20160209',3,2),
    (8,'20160207','20160201',NULL,3);

-- select distinct Visit ids
SELECT DISTINCT
    Visit
INTO
    #visit_ids
FROM
    #tt
WHERE
    Visit IS NOT NULL;

-- create dynamic select columns (forcing order by Visit id)
DECLARE @sel_cols NVARCHAR(MAX)=STUFF((
    SELECT
        ',[FromD-'+CAST(Visit AS VARCHAR(3))+'visit]=MAX(CASE WHEN Visit='+CAST(Visit AS VARCHAR(3))+' THEN FromDate END)'+
        ',[ToD-'+CAST(Visit AS VARCHAR(3))+'visit]=MAX(CASE WHEN Visit='+CAST(Visit AS VARCHAR(3))+' THEN ToDate END)'
    FROM
        #visit_ids
    ORDER BY
        Visit
    FOR
        XML PATH('')
    ),1,1,''
);

DECLARE @stmt NVARCHAR(MAX)=N'
    SELECT
        id=ROW_NUMBER() OVER (ORDER BY UserId),
        UserId,'+
        @sel_cols+'
    FROM
        #tt
    WHERE
        Visit IS NOT NULL
    GROUP BY
        UserId;
';

EXECUTE sp_executesql @stmt;

DROP TABLE #visit_ids;
DROP TABLE #tt;

结果:

+----+--------+-------------------------+-------------------------+-------------------------+------------+-------------------------+-------------------------+
| id | UserId |      FromD-1visit       |       ToD-1visit        |      FromD-2visit       | ToD-2visit |      FromD-3visit       |       ToD-3visit        |
+----+--------+-------------------------+-------------------------+-------------------------+------------+-------------------------+-------------------------+
|  1 |      2 | 2017-05-17 00:00:00.000 | 2017-05-17 00:00:00.000 | 2016-02-02 00:00:00.000 | NULL       | 2016-02-01 00:00:00.000 | 2016-02-09 00:00:00.000 |
+----+--------+-------------------------+-------------------------+-------------------------+------------+-------------------------+-------------------------+

答案 1 :(得分:0)

试试这个

SQL Fiddle

select 
    f1.ID, f1.FromDate as 'FromD-1visit', 
    f1.ToDate as 'ToD-1visit',
    f2.FromDate as 'FromD-2visit', f2.ToDate as 'ToD-2visit',
    f3.FromDate as 'FromD-3visit', f3.ToDate as 'ToD-1visit',
    f1.UserID
from
    user_travel f1
left join  
    user_travel f2 on f2.UserID = f1.UserID and f2.Visit = 2
left join  
    user_travel f3 on f3.UserID = f1.UserID and f3.Visit = 3
where 
    f1.Visit = 1 and f1.UserID = 2