答案 0 :(得分:1)
我建议你改变表格的设计。这是存储数据的不好方法,它不遵循规范化规则。您需要有另一个联结表来存储rownum的CR值。
无论如何,如果你需要为这些表写查询,那么将A1表连接到B1表3次并从那里得到descr。
UPDATE(也使用@gotqn回答中的PIVOT查询):
正如你所说,可能会有很多CR *列...我讨厌游标,但是你需要它:
DECLARE @columnName VARCHAR(200),
@query VARCHAR(8000) = 'SELECT b.rownum ',
@joins VARCHAR(8000) = '',
@tmpColumnValue VARCHAR(100);
DECLARE @getDescr CURSOR
SET @getDescr = CURSOR FOR
select name
from sys.columns where object_name(object_id) = 'B1' ANd name like 'CR%'
OPEN @getDescr
FETCH NEXT
FROM @getDescr INTO @columnName
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @tmpColumnValue = pr_desc FROM A1 WHERE pr_id = @columnName;
SET @query = @query + ', b.' + @columnName + ' AS ' + @tmpColumnValue;
PRINT @columnName
FETCH NEXT
FROM @getDescr INTO @columnName
END
CLOSE @getDescr
DEALLOCATE @getDescr
SET @query = @query + ' FROM B1 b ';
EXECUTE (@query)
使用PIVOT查询:
DECLARE @Descriptions VARCHAR(MAX);
DECLARE @columns VARCHAR(MAX);
SELECT @Descriptions = STUFF
(
(
SELECT ',[' + [pr_desc] + ']'
FROM A1
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1
,1
,''
)
SELECT @columns = STUFF
(
(
SELECT ',[' + [name] + ']'
FROM sys.columns
WHERE object_name(object_id) = 'B1' ANd name like 'CR%'
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1
,1
,''
)
SET @query = '
SELECT *
FROM
(
SELECT [rownum]
,[value]
,[pr_desc]
FROM B1
UNPIVOT
(
[value] FOR [column] IN (' + @columns + ')
) PVT
INNER JOIN A1 DS
ON PVT.[column] = DS.[pr_id]
) PVT
PIVOT
(
MAX([value]) FOR [pr_desc] IN (' + @Descriptions + ')
) PVT;
';
EXEC (@query)
答案 1 :(得分:1)
在T-SQL的上下文中,可以按照以下步骤完成:
无人值守数据
DECLARE @A1 TABLE
(
[pr_id] CHAR(3)
,[pr_desc] VARCHAR(12)
);
DECLARE @B1 TABLE
(
[rownum] TINYINT
,[name] VARCHAR(12)
,[Date] DATE
,[CR1] INT
,[CR2] INT
,[CR3] INT
);
INSERT INTO @A1 ([pr_id], [pr_desc])
VALUES ('CR1', 'Desc1')
,('CR2', 'Desc2')
,('CR3', 'Desc3');
INSERT INTO @B1 ([rownum], [name], [Date], [CR1], [CR2], [CR3])
VALUES (1, 'Jon', '1/1/2017', 10, 50, 100)
,(2, 'Jon', '2/1/2017', 60, 100, 500);
SELECT *
FROM @B1
UNPIVOT
(
[value] FOR [column] IN ([CR1], [CR2], [CR3])
) PVT;
加入@A1
表格以获取说明:
SELECT *
FROM @B1
UNPIVOT
(
[value] FOR [column] IN ([CR1], [CR2], [CR3])
) PVT
INNER JOIN @A1 DS
ON PVT.[column] = DS.[pr_id];
再次调整数据(注意,我们只选择所需的列)
SELECT *
FROM
(
SELECT [rownum]
,[value]
,[pr_desc]
FROM @B1
UNPIVOT
(
[value] FOR [column] IN ([CR1], [CR2], [CR3])
) PVT
INNER JOIN @A1 DS
ON PVT.[column] = DS.[pr_id]
) PVT
PIVOT
(
MAX([value]) FOR [pr_desc] IN ([Desc1], [Desc2], [Desc3])
) PVT;
如您所见,为了使用UNPIVOT
和PIVOT
,我们有很多硬编码值。因此,最好使用动态T-SQL。
CREATE TABLE A1
(
[pr_id] CHAR(3)
,[pr_desc] VARCHAR(12)
);
CREATE TABLE B1
(
[rownum] TINYINT
,[name] VARCHAR(12)
,[Date] DATE
,[CR1] INT
,[CR2] INT
,[CR3] INT
);
INSERT INTO A1 ([pr_id], [pr_desc])
VALUES ('CR1', 'Desc1')
,('CR2', 'Desc2')
,('CR3', 'Desc3');
INSERT INTO B1 ([rownum], [name], [Date], [CR1], [CR2], [CR3])
VALUES (1, 'Jon', '1/1/2017', 10, 50, 100)
,(2, 'Jon', '2/1/2017', 60, 100, 500);
DECLARE @DynamicTSQLStatement NVARCHAR(MAX);
DECLARE @Descriptions NVARCHAR(MAX);
SELECT @Descriptions = STUFF
(
(
SELECT ',[' + [pr_desc] + ']'
FROM A1
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1
,1
,''
)
SET @DynamicTSQLStatement = '
SELECT *
FROM
(
SELECT [rownum]
,[value]
,[pr_desc]
FROM B1
UNPIVOT
(
[value] FOR [column] IN ([CR1], [CR2], [CR3])
) PVT
INNER JOIN A1 DS
ON PVT.[column] = DS.[pr_id]
) PVT
PIVOT
(
MAX([value]) FOR [pr_desc] IN (' + @Descriptions + ')
) PVT;
';
EXEC sp_executesql @DynamicTSQLStatement;
DROP TABLE A1;
DROP TABLE B1;
答案 2 :(得分:0)
你可以使用它。
DECLARE @COLNAMES VARCHAR(4000) =
CONVERT(VARCHAR(4000),
(SELECT * FROM (VALUES(NULL) ) AS X(DUMY)
LEFT JOIN B1 ON 1= 0
FOR XML RAW, ELEMENTS XSINIL ) )
SET @COLNAMES =
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@COLNAMES,'<row xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">','')
, '<DUMY xsi:nil="true"/>','')
, ' xsi:nil="true"/><',', ')
, ', /row>','')
, '<','')
SELECT
@COLNAMES = REPLACE(@COLNAMES, pr_id, pr_id + ' ['+ pr_desc+ ']')
FROM A1
DECLARE @Query NVARCHAR(4000) = 'SELECT ' + @COLNAMES + ' FROM B1'
PRINT @Query
EXEC sp_executesql @Query
生成的查询:
SELECT rownum, Name, Date, CR1 [Desc1], CR2 [Desc2], CR3 [Desc3] FROM B1
结果:
rownum Name Date Desc1 Desc2 Desc3
----------- -------------------------------------------------- -------------------- ----------- ----------- -----------
1 Jon 1/1/2017 10 50 100
2 Jon 2/1/2017 60 100 500