在下面的例子中我有2条记录,但每个id的no或记录都没有修复......
SELECT InsuredMemberIdentifier,CoverageStartDate,CoverageEndDate FROM
APCD.DBO.EdgeServer_EligibilityConsolidated_Part3 WHERE
InsuredMemberIdentifier=10190
输出是:
InsuredMemberIdentifier | CoverageStartDate | CoverageEndDate
10190 2014-01-01 2014-01-31
10190 2014-02-01 2014-09-30
必需输出:
10190 | 2014-01-01 | 2014-01-31 | 2014-02-01 | 2014-09-30
答案 0 :(得分:0)
有一种方法可以使用FOR XML
运算符将日期值连接到单个列中:
DECLARE @tb AS TABLE
(
InsuredMemberIdentifier INT
,CoverageStartDate DATE
,CoverageEndDate DATE
)
INSERT INTO @tb VALUES (10190, '2014-01-01', '2014-01-31');
INSERT INTO @tb VALUES (10190, '2014-02-01', '2014-09-30');
INSERT INTO @tb VALUES (10191, '2014-02-01', '2014-09-30');
SELECT DISTINCT InsuredMemberIdentifier
,ISNULL(STUFF(
(SELECT ' ' + CAST(CoverageStartDate AS NVARCHAR(15)) + ' ' + CAST(CoverageEndDate AS NVARCHAR(15))
FROM @tb tb_inner
WHERE tb_inner.InsuredMemberIdentifier = tb.InsuredMemberIdentifier
FOR XML PATH (''))
,1,1,''), '') AS ConcatenatedDates
FROM @tb tb
WHERE InsuredMemberIdentifier = 10190
答案 1 :(得分:0)
样本表
CREATE TABLE #EdgeServer_EligibilityConsolidated_Part3 (InsuredMemberIdentifier INT, CoverageStartDate DATE, CoverageEndDate DATE)
INSERT INTO #EdgeServer_EligibilityConsolidated_Part3
SELECT 10190 , '2014-01-01', '2014-01-31'
UNION ALL
SELECT 10190, '2014-02-01', '2014-09-30'
第1步
1.由于您需要根据两个列值将行转换为列(Pivot
),因此您需要先将两列中的值转换为一列(称为Unpivot
)。
2.由于您是pivot
的新手,我正在创建一个临时表来保存值,以便您可以轻松理解。
所以查询将如下
SELECT ROW_NUMBER() OVER(ORDER BY DATES) COLUMNHEADERS,
InsuredMemberIdentifier,DATES
INTO #TEMP
FROM #EdgeServer_EligibilityConsolidated_Part3
CROSS apply (VALUES (CoverageStartDate),
(CoverageEndDate)) cs (DATES)
WHERE InsuredMemberIdentifier = 10190
CROSS APPLY
的工作方式与
SELECT InsuredMemberIdentifier,CoverageStartDate
FROM #EdgeServer_EligibilityConsolidated_Part3
WHERE InsuredMemberIdentifier = 10190
UNION ALL
SELECT InsuredMemberIdentifier,CoverageEndDate
FROM #EdgeServer_EligibilityConsolidated_Part3
WHERE InsuredMemberIdentifier = 10190
所以不要混淆。
第2步
此变量中的值将是作为pivot
的一部分生成的表的列名
DECLARE @cols NVARCHAR (MAX)
SELECT @cols = COALESCE (@cols + ',[' + CAST(COLUMNHEADERS AS VARCHAR(50)) + ']',
'[' + CAST(COLUMNHEADERS AS VARCHAR(50)) + ']')
FROM (SELECT COLUMNHEADERS FROM #TEMP) PV
ORDER BY COLUMNHEADERS
第3步
由于您无法预测日期值或硬编码日期值的数量(因为列数将是动态的,无法通过逗号写入),您需要使用Dynamic Sql
。
DECLARE @query NVARCHAR(MAX)
SET @query = '--This is the query result - InsuredMemberIdentifier and columns with dates
SELECT InsuredMemberIdentifier,' + @cols + ' FROM
(
-- Here you will select the columns before pivoting. COLUMNHEADERS will be name of column
-- and each date will be displayed under that column
SELECT COLUMNHEADERS,InsuredMemberIdentifier,DATES
FROM #TEMP
) x
PIVOT
(
-- Tells what should be the values in each column(ie, values in 2014-01-01,2014-01-31 etc)
MIN(DATES)
-- You will tell SQL to show values in @cols to be the column names
-- by taking corresponding DATES from its corresponding COLUMNHEADERS
FOR [COLUMNHEADERS] IN (' + @cols + ')
) p
'
EXEC SP_EXECUTESQL @query
当您提供PRINT @QUERY
而不是EXEC SP_EXECUTESQL @query
时,它会显示以下结果
请参阅,SQL Server为您动态生成了列名1,2,3,4
,因为您使用的是Dynamic Sql
。如果只有两个日期,则只会生成列名1,2
。
最终结果
答案 2 :(得分:0)
选择a.InsuredMemberIdentifier,a.CoverageStartDate,a.CoverageEndDate,b.CoverageStartDate,b.CoverageEndDate from (选择top 1 *,ROW_NUMBER()over(InsuredMemberIdentifier order by(select 0))by r from APCD.DBO.EdgeServer_EligibilityConsolidated_Part3 order by r)a, (选择top 1 *,ROW_NUMBER()over(InsuredMemberIdentifier order by(select 0))by r from APCD.DBO.EdgeServer_EligibilityConsolidated_Part3 order by r desc)b
答案 3 :(得分:-1)
看一下SQL pivot和unpivot
https://technet.microsoft.com/en-us/library/ms177410%28v=sql.105%29.aspx