为此使用动态数据透视查询?
Use Dyamic Pivot query for this?
我有以下 table。 (此table中没有主键)
ID | IC | Name | UGCOS | MCOS
---------------------------------------------------------
1AA | A123456B | Edmund | Australia | Denmark
1AA | A123456B | Edmund | Australia | France
2CS | C435664C | Grace | Norway | NULL
3TG | G885595H | Rae | NULL | Japan
我需要这样的结果。
ID | IC | Name | UGCOS | MCOS | MCOS1
--------------------------------------------------------------------
1AA | A123456B | Edmund | Australia | Denmark | France
2CS | C435664C | Grace | Norway | NULL | NULL
3TG | G885595H | Rae | NULL | Japan | NULL
用谷歌搜索了一下,似乎 PIVOT 是我需要做的。但是我不确定如何将其应用到我的 table 中。如果有人可以帮助我,那将是很大的帮助。谢谢!
使用 Cross Apply 和 Pivot 我们可以实现这个
DECLARE @Table1 TABLE
( ID varchar(3), IC varchar(8), Name varchar(6), UGCOS varchar(9), MCOS varchar(7))
;
INSERT INTO @Table1
( ID , IC , Name , UGCOS , MCOS )
VALUES
('1AA', 'A123456B', 'Edmund', 'Australia', 'Denmark'),
('1AA', 'A123456B', 'Edmund', 'Australia', 'France'),
('2CS', 'C435664C', 'Grace', 'Norway', NULL),
('3TG', 'G885595H', 'Rae', NULL, 'Japan')
;
Select ID , IC , Name , UGCOS,MAX([MCOS1])[MCOS1],MAX([MCOS2])[MCOS2] from (
select ID , IC , Name , UGCOS , MCOS,col,val,col +''+CAST(ROW_NUMBER()OVER(PARTITION BY ID ORDER BY col) AS VARCHAR)RN from @Table1
CROSS APPLY (values('MCOS',MCOS))CS(col,val))T
PIVOT (MAX(val) FOR RN IN ([MCOS1],[MCOS2]))PVT
GROUP BY ID , IC , Name , UGCOS
您是否总是希望将最多 2 行数据转换为列?如果是这样,这对你有用;
CREATE TABLE #TableName (ID varchar(3), IC varchar(8), Name varchar(6), UCGOS varchar(9), MCOS varchar(7))
INSERT INTO #TableName
VALUES
('1AA','A123456B','Edmund','Australia','Denmark')
,('1AA','A123456B','Edmund','Australia','France')
,('2CS','C435664C','Grace','Norway',NULL)
,('3TG','G885595H','Rae',NULL,'Japan')
SELECT DISTINCT a.ID
,a.IC
,a.NAME
,a.UCGOS
,b.Mcos1 MCOS
,c.Mcos2 MCOS1
FROM #TableName a
LEFT JOIN (
SELECT ID
,MAX(MCOS) Mcos1
FROM #TableName
GROUP BY ID
) b ON a.ID = b.ID
LEFT JOIN (
SELECT ID
,MIN(MCOS) Mcos2
FROM #TableName
GROUP BY ID
) c ON a.ID = c.ID
AND (
b.ID = c.ID
AND b.Mcos1 <> c.Mcos2
)
DROP TABLE #TableName
给你你想要的结果。
这是一个包含串联结果的建议:
CREATE TABLE #tmpTbl (ID VARCHAR(100),IC VARCHAR(100),Name VARCHAR(100),UGCOS VARCHAR(100),MCOS VARCHAR(100))
INSERT INTO #tmpTbl VALUES
('1AA','A123456B','Edmund','Australia','Denmark')
,('1AA','A123456B','Edmund','Australia','France')
,('2CS','C435664C','Grace','Norway',NULL)
,('3TG','G885595H','Rae',NULL,'Japan');
SELECT ID,IC,Name,UGCOS,
(
STUFF(
(
SELECT ' ,' + x.MCOS
FROM #tmpTbl AS x
WHERE x.ID=outerTbl.ID
FOR XML PATH('')
),1,2,''
)
) AS MCOS
FROM #tmpTbl AS outerTbl
GROUP BY ID,IC,Name,UGCOS;
GO
DROP TABLE #tmpTbl;
结果
1AA A123456B Edmund Australia Denmark ,France
2CS C435664C Grace Norway NULL
3TG G885595H Rae NULL Japan
我将创建第二个答案,因为这种方法与我的第一个完全不同:
此动态查询将首先找到不同 ID 的最大计数,然后构建动态数据透视表
CREATE TABLE #tmpTbl (ID VARCHAR(100),IC VARCHAR(100),Name VARCHAR(100),UGCOS VARCHAR(100),MCOS VARCHAR(100))
INSERT INTO #tmpTbl VALUES
('1AA','A123456B','Edmund','Australia','Denmark')
,('1AA','A123456B','Edmund','Australia','France')
,('1AA','A123456B','Edmund','Australia','OneMore')
,('2CS','C435664C','Grace','Norway',NULL)
,('3TG','G885595H','Rae',NULL,'Japan');
GO
DECLARE @maxCount INT=(SELECT TOP 1 COUNT(*) FROM #tmpTbl GROUP BY ID ORDER BY COUNT(ID) DESC);
DECLARE @colNames VARCHAR(MAX)=
(
STUFF
(
(
SELECT TOP(@maxCount)
',MCOS' + CAST(ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS VARCHAR(10))
FROM sys.objects --take any large table or - better! - an numbers table or a tally CTE
FOR XML PATH('')
),1,1,''
)
);
DECLARE @cmd VARCHAR(MAX)=
'SELECT p.*
FROM
(
SELECT *
,''MCOS'' + CAST(ROW_NUMBER() OVER(PARTITION BY ID ORDER BY (SELECT NULL)) AS VARCHAR(10)) AS colName
FROM #tmpTbl
) AS tbl
PIVOT
(
MIN(MCOS) FOR colName IN(' + @colNames + ')
) AS p';
EXEC(@cmd);
GO
DROP TABLE #tmpTbl;
结果
1AA A123456B Edmund Australia Denmark France OneMore
2CS C435664C Grace Norway NULL NULL NULL
3TG G885595H Rae NULL Japan NULL NULL
我有以下 table。 (此table中没有主键)
ID | IC | Name | UGCOS | MCOS
---------------------------------------------------------
1AA | A123456B | Edmund | Australia | Denmark
1AA | A123456B | Edmund | Australia | France
2CS | C435664C | Grace | Norway | NULL
3TG | G885595H | Rae | NULL | Japan
我需要这样的结果。
ID | IC | Name | UGCOS | MCOS | MCOS1
--------------------------------------------------------------------
1AA | A123456B | Edmund | Australia | Denmark | France
2CS | C435664C | Grace | Norway | NULL | NULL
3TG | G885595H | Rae | NULL | Japan | NULL
用谷歌搜索了一下,似乎 PIVOT 是我需要做的。但是我不确定如何将其应用到我的 table 中。如果有人可以帮助我,那将是很大的帮助。谢谢!
使用 Cross Apply 和 Pivot 我们可以实现这个
DECLARE @Table1 TABLE
( ID varchar(3), IC varchar(8), Name varchar(6), UGCOS varchar(9), MCOS varchar(7))
;
INSERT INTO @Table1
( ID , IC , Name , UGCOS , MCOS )
VALUES
('1AA', 'A123456B', 'Edmund', 'Australia', 'Denmark'),
('1AA', 'A123456B', 'Edmund', 'Australia', 'France'),
('2CS', 'C435664C', 'Grace', 'Norway', NULL),
('3TG', 'G885595H', 'Rae', NULL, 'Japan')
;
Select ID , IC , Name , UGCOS,MAX([MCOS1])[MCOS1],MAX([MCOS2])[MCOS2] from (
select ID , IC , Name , UGCOS , MCOS,col,val,col +''+CAST(ROW_NUMBER()OVER(PARTITION BY ID ORDER BY col) AS VARCHAR)RN from @Table1
CROSS APPLY (values('MCOS',MCOS))CS(col,val))T
PIVOT (MAX(val) FOR RN IN ([MCOS1],[MCOS2]))PVT
GROUP BY ID , IC , Name , UGCOS
您是否总是希望将最多 2 行数据转换为列?如果是这样,这对你有用;
CREATE TABLE #TableName (ID varchar(3), IC varchar(8), Name varchar(6), UCGOS varchar(9), MCOS varchar(7))
INSERT INTO #TableName
VALUES
('1AA','A123456B','Edmund','Australia','Denmark')
,('1AA','A123456B','Edmund','Australia','France')
,('2CS','C435664C','Grace','Norway',NULL)
,('3TG','G885595H','Rae',NULL,'Japan')
SELECT DISTINCT a.ID
,a.IC
,a.NAME
,a.UCGOS
,b.Mcos1 MCOS
,c.Mcos2 MCOS1
FROM #TableName a
LEFT JOIN (
SELECT ID
,MAX(MCOS) Mcos1
FROM #TableName
GROUP BY ID
) b ON a.ID = b.ID
LEFT JOIN (
SELECT ID
,MIN(MCOS) Mcos2
FROM #TableName
GROUP BY ID
) c ON a.ID = c.ID
AND (
b.ID = c.ID
AND b.Mcos1 <> c.Mcos2
)
DROP TABLE #TableName
给你你想要的结果。
这是一个包含串联结果的建议:
CREATE TABLE #tmpTbl (ID VARCHAR(100),IC VARCHAR(100),Name VARCHAR(100),UGCOS VARCHAR(100),MCOS VARCHAR(100))
INSERT INTO #tmpTbl VALUES
('1AA','A123456B','Edmund','Australia','Denmark')
,('1AA','A123456B','Edmund','Australia','France')
,('2CS','C435664C','Grace','Norway',NULL)
,('3TG','G885595H','Rae',NULL,'Japan');
SELECT ID,IC,Name,UGCOS,
(
STUFF(
(
SELECT ' ,' + x.MCOS
FROM #tmpTbl AS x
WHERE x.ID=outerTbl.ID
FOR XML PATH('')
),1,2,''
)
) AS MCOS
FROM #tmpTbl AS outerTbl
GROUP BY ID,IC,Name,UGCOS;
GO
DROP TABLE #tmpTbl;
结果
1AA A123456B Edmund Australia Denmark ,France
2CS C435664C Grace Norway NULL
3TG G885595H Rae NULL Japan
我将创建第二个答案,因为这种方法与我的第一个完全不同:
此动态查询将首先找到不同 ID 的最大计数,然后构建动态数据透视表
CREATE TABLE #tmpTbl (ID VARCHAR(100),IC VARCHAR(100),Name VARCHAR(100),UGCOS VARCHAR(100),MCOS VARCHAR(100))
INSERT INTO #tmpTbl VALUES
('1AA','A123456B','Edmund','Australia','Denmark')
,('1AA','A123456B','Edmund','Australia','France')
,('1AA','A123456B','Edmund','Australia','OneMore')
,('2CS','C435664C','Grace','Norway',NULL)
,('3TG','G885595H','Rae',NULL,'Japan');
GO
DECLARE @maxCount INT=(SELECT TOP 1 COUNT(*) FROM #tmpTbl GROUP BY ID ORDER BY COUNT(ID) DESC);
DECLARE @colNames VARCHAR(MAX)=
(
STUFF
(
(
SELECT TOP(@maxCount)
',MCOS' + CAST(ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS VARCHAR(10))
FROM sys.objects --take any large table or - better! - an numbers table or a tally CTE
FOR XML PATH('')
),1,1,''
)
);
DECLARE @cmd VARCHAR(MAX)=
'SELECT p.*
FROM
(
SELECT *
,''MCOS'' + CAST(ROW_NUMBER() OVER(PARTITION BY ID ORDER BY (SELECT NULL)) AS VARCHAR(10)) AS colName
FROM #tmpTbl
) AS tbl
PIVOT
(
MIN(MCOS) FOR colName IN(' + @colNames + ')
) AS p';
EXEC(@cmd);
GO
DROP TABLE #tmpTbl;
结果
1AA A123456B Edmund Australia Denmark France OneMore
2CS C435664C Grace Norway NULL NULL NULL
3TG G885595H Rae NULL Japan NULL NULL