具有两列的 SQL Server Pivot 动态 Sql
更新 2022-03-04
这是我的 fiddle,显示表格和样本值
创建表代码( id int 主键 , labVal varchar(50) , 标签 varchar(50) ) 插入代码 价值观 (1,'代码1','重要1') ,(2,'代码2','重要2') ,(3,'代码3','重要3') 创建表客户端( id int 主键 , 工资小数 , fkCode int 外键引用代码(id) ) 插入客户端 值 (1,120,3) ,(2,1220,2) ,(3,120, 1) ;
这些是预期结果:
id | important 1 | Salary 1 | important 2 | salary 2 | important 3 | salary 3 | ... |
---|---|---|---|---|---|---|---|
1 | code1 | 120 | NULL | NULL | NULL | NULL | ... |
2 | NULL | NULL | code2 | 1220 | NULL | NULL | ... |
3 | NULL | NULL | NULL | NULL | code3 | 120 | 。 .. |
我可以使用下面的查询获取“重要 1,2,3...”的正确数据。但我无法插入“Salary1,2,3,...”的数据,因为数据透视表只允许一系列列。
SELECT * FROM
(
SELECT
cd.id,
cd.label,
cd.labVal,
c.salary
FROM
code cd
inner join client c on c.fkcode = cd.id
) t
PIVOT(
max(labVal)
FOR label IN (
[Important 1]
,[salary1]
,[Important 2]
,[salary2]
,[Important 3]
,[salary3])
) AS pivot_table;
结果:
<前>id |薪资|重要1 |工资1 |重要2 |工资2 |重要 3 |工资3 -: | -----: | :---------- | :------ | :---------- | :------ | :---------- | :------ 1 | 120 | 120代码1 | 空 | 空 | 空 | 空 | 空 3 | 120 | 120 空 | 空 | 空 | 空 |代码3 | 空 2 | 1220 | 1220 空 | 空 |代码2 | 空 | 空 | 空
原始帖子:
我希望能够使用正确的数据生成此示例,
------------------------------------------------------------------------------------------------
| id | whatever | important 1 | custom 1 | important 2 | custom 2 | important 3 | custom 3 |...|
|-----------------------------------------------------------------------------------------------
|x1 | a | NULL | NULL | code1 | 120 | NULL | NULL | |
------------------------------------------------------------------------------------------------
|x2 | b | code2 | 450 | NULL | NULL | NULL | NULL | |
------------------------------------------------------------------------------------------------
|x2 | b | NULL | NULL | code3 | 250 | NULL | NULL | |
------------------------------------------------------------------------------------------------
我能够获得“important1,2,3...”的正确数据,但无法插入自定义数据”由于数据透视表只允许一系列列,因此我无法创建两个数据透视表,因为它们看起来像这样,
---------------------------------------------------------------------------------------------
| id | whatever | important 1 | important2| important3 | custom 1 | custom 2 |custom 3 |
---------------------------------------------------------------------------------------------
|x | | | | | | | |
---------------------------------------------------------------------------------------------
|x | | | | | | | |
---------------------------------------------------------------------------------------------
“自定义”列是一个临时字段,其中必须包含十进制值,并且每次“重要”列显示时都会重复
。 important”列标题来自一个表,其中包含我转过的名称使用数据透视将行转换为列,并从不同的列分配所需的值。 但自定义列不存在于任何表中,但我想放入其中的值确实存在,问题是,我使用动态 sql 生成带有 row_number 的“自定义”列名称,以避免重复列错误。
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX);
SET @cols = STUFF((SELECT ',' + QUOTENAME(c.important) +','+ QUOTENAME( 'custom' + CAST(ROW_NUMBER() OVER (ORDER BY c.id) as VARCHAR)) as tempfield
FROM tableName rp
inner join tblsecond c on rp.sTbId = c.id
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
print @cols
----- this @cols
---- will print [important first row to column],[custom1],[important second row to column],[custom2]..
set @query = 'SELECT * into #temp from
(
select c.id, c.whatever, c.name, c.customColumnValue
FROM tableName rp
inner join tblsecond c on rp.sTbId = c.id
) x
pivot
(
max(name)
for important in (' + @cols +')
) p select * from #temp
'
execute(@query)
示例数据位于此处
Update 2022-03-04
Here is my fiddle, showing the tables and sample values
CREATE TABLE code ( id int primary key , labVal varchar(50) , Label varchar(50) ) INSERT INTO code VALUES (1,'Code1','Important 1') ,(2,'Code2','Important 2') ,(3,'Code3','Important 3') CREATE TABLE client ( id int primary key , Salary decimal , fkCode int foreign key references code (id) ) INSERT INTO client VALUES (1,120,3) ,(2,1220,2) ,(3,120, 1) ;
These are the expected results:
id | Important 1 | Salary 1 | Important 2 | Salary 2 | Important 3 | Salary 3 | ... |
---|---|---|---|---|---|---|---|
1 | code1 | 120 | NULL | NULL | NULL | NULL | ... |
2 | NULL | NULL | code2 | 1220 | NULL | NULL | ... |
3 | NULL | NULL | NULL | NULL | code3 | 120 | ... |
I am able to get the right data for "Important 1,2,3..." using the query below. But am unable to insert data for "Salary1,2,3,..." since pivot only allows one series of columns.
SELECT * FROM
(
SELECT
cd.id,
cd.label,
cd.labVal,
c.salary
FROM
code cd
inner join client c on c.fkcode = cd.id
) t
PIVOT(
max(labVal)
FOR label IN (
[Important 1]
,[salary1]
,[Important 2]
,[salary2]
,[Important 3]
,[salary3])
) AS pivot_table;
Results:
id | salary | Important 1 | salary1 | Important 2 | salary2 | Important 3 | salary3 -: | -----: | :---------- | :------ | :---------- | :------ | :---------- | :------ 1 | 120 | Code1 | null | null | null | null | null 3 | 120 | null | null | null | null | Code3 | null 2 | 1220 | null | null | Code2 | null | null | null
Original Post:
I want to be able to generate this example with the correct data
------------------------------------------------------------------------------------------------
| id | whatever | important 1 | custom 1 | important 2 | custom 2 | important 3 | custom 3 |...|
|-----------------------------------------------------------------------------------------------
|x1 | a | NULL | NULL | code1 | 120 | NULL | NULL | |
------------------------------------------------------------------------------------------------
|x2 | b | code2 | 450 | NULL | NULL | NULL | NULL | |
------------------------------------------------------------------------------------------------
|x2 | b | NULL | NULL | code3 | 250 | NULL | NULL | |
------------------------------------------------------------------------------------------------
I am able to get the right data for "important1,2,3..." but unable to insert data for custom" since pivot only allows one series of columns, I can't create two pivot because they would look like this
---------------------------------------------------------------------------------------------
| id | whatever | important 1 | important2| important3 | custom 1 | custom 2 |custom 3 |
---------------------------------------------------------------------------------------------
|x | | | | | | | |
---------------------------------------------------------------------------------------------
|x | | | | | | | |
---------------------------------------------------------------------------------------------
the "custom" column is a tempfield which must have decimal values in it and get repeated each time "important" column shows.
The "important" column header is from a table which hold names which i turned from rows into columns using pivot and assigned the desired values from a different column.
but custom column doesn't exist in any table whatsoever but the values that I would like to put inside it do exist, the problem is, I am using dynamic sql to generate the "custom" column name with row_number to avoid duplicate column error.
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX);
SET @cols = STUFF((SELECT ',' + QUOTENAME(c.important) +','+ QUOTENAME( 'custom' + CAST(ROW_NUMBER() OVER (ORDER BY c.id) as VARCHAR)) as tempfield
FROM tableName rp
inner join tblsecond c on rp.sTbId = c.id
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
print @cols
----- this @cols
---- will print [important first row to column],[custom1],[important second row to column],[custom2]..
set @query = 'SELECT * into #temp from
(
select c.id, c.whatever, c.name, c.customColumnValue
FROM tableName rp
inner join tblsecond c on rp.sTbId = c.id
) x
pivot
(
max(name)
for important in (' + @cols +')
) p select * from #temp
'
execute(@query)
The sample data is here
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为您将需要多个 PIVOT。由于一些事情,
CodeX,CodeY,...
Salary1,Salary2,...
"CodeX,Salary1,CodeY,Salary2....*
你有权利那里的想法是,构建一个两列的串联列表,但实际上您需要 3 个变量:1)用于代码列,2)用于工资列,3)用于选择。 列表。
注意:在所有查询中必须使用相同的 ORDER BY
然后在 SELECT 中使用三个变量:
结果:
db<>fiddle 此处
I think you will need multiple PIVOT's. It's made slightly more complicated by a few things
CodeX,CodeY,...
Salary1,Salary2,...
"CodeX,Salary1,CodeY,Salary2....*
You had the right idea there, building a concatenated list of both columns. But you'll actually need 3 variables: 1) For code columns 2) for salary columns and 3) for select list.
Note: Must use the same ORDER BY in all queries
Then use the three variable in your SELECT:
Results:
db<>fiddle here