gpt4 book ai didi

sql-server - 不聚合的旋转

转载 作者:行者123 更新时间:2023-12-03 02:40:51 25 4
gpt4 key购买 nike

我正在尝试pivot without aggregation ,并且遇到了一点墙壁。

这是我正在尝试使用的示例 T-SQL:

declare @optionalFields table (ParentId int, Name nvarchar(50), Value nvarchar(50));
insert into @optionalFields values (1, 'Field1', 'Foo');
insert into @optionalFields values (1, 'Field2', 'Bar');
insert into @optionalFields values (1, 'Field3', '42');
insert into @optionalFields values (2, 'Field1', 'Bar');
insert into @optionalFields values (2, 'Field2', 'Foo');
insert into @optionalFields values (2, 'Field3', '24');

declare @data table (Id int, Name nvarchar(50));
insert into @data values (1, 'Test record 1');
insert into @data values (2, 'Test record 2');

declare @joined table (Id int, Name nvarchar(50), OptionalFieldName nvarchar(50), OptionalFieldValue nvarchar(50));
insert into @joined
select
data.Id
,data.Name
,opt.Name
,opt.Value
from @data data
inner join @optionalFields opt on data.Id = opt.ParentId

declare @cols as nvarchar(max) =
stuff((select distinct ',' + quotename(OptionalFieldName) from @joined for xml path(''), type).value('.', 'nvarchar(max)'), 1, 1, '');

select * into #tmp from @joined
-- just to see that it's returning the expected values (it does)
select
Id
,Name
,OptionalFieldName
,OptionalFieldValue
,row_number() over (partition by Id order by Id) RN
from #tmp -- this is the FROM clause in the below dynamic-sql query

declare @query as nvarchar(max) = '
select Id, Name, ' + @cols + '
from (select Id, Name, OptionalFieldName, OptionalFieldValue, row_number() over (partition by Id order by Id) RN from #tmp) src
pivot (max(OptionalFieldName) for RN in (' + @cols + ')) pvt';

execute(@query);
drop table #tmp;

SSMS 给了我 2 个错误:

  • Msg 8114, Level 16, State 1, Line 4 Error converting data type nvarchar to bigint.
  • Msg 473, Level 16, State 1, Line 4 The incorrect value "Field1" is supplied in the PIVOT operator.

“调试”选择语句返回以下内容:

3 rows per "test record", as expected

这篇文章(上面的链接)看起来很有希望,但我似乎无法让它发挥作用。我究竟做错了什么?或者这篇文章完全错误,而我想做的事情是不可能的?

我见过许多类似的SO问题,但它们要么涉及可以“仅适用于”聚合的全数字字段,要么涉及可以作为简单连接实现的已知列 - 我不知道什么我要选择的 OptionalFieldName 值,而 OptionalFieldValue 值是根本无法聚合的字符串,至少据我所知。

最佳答案

我有点困惑为什么你试图使用row_number()来欺骗这个。即使您有字符串值,您仍然可以聚合它 - 您只需使用 maxmin 即可获得结果。

我总是建议首先尝试使用硬编码值编写查询,尤其是在尝试使用动态 SQL 之前使用 PIVOT 时。我不确定为什么你不能这样编写查询:

select Id, Name, Field1, Field2, Field3
from
(
select
Id
,Name
,OptionalFieldName
,OptionalFieldValue
from #tmp
) d
pivot
(
max(OptionalFieldValue)
for OptionalFieldName in (Field1, Field2, Field3)
) piv;

See a Demo .

如果你真的需要动态SQL,你就这样写:

declare @optionalFields table (ParentId int, Name nvarchar(50), Value nvarchar(50));
insert into @optionalFields values (1, 'Field1', 'Foo');
insert into @optionalFields values (1, 'Field2', 'Bar');
insert into @optionalFields values (1, 'Field3', '42');
insert into @optionalFields values (2, 'Field1', 'Bar');
insert into @optionalFields values (2, 'Field2', 'Foo');
insert into @optionalFields values (2, 'Field3', '24');

declare @data table (Id int, Name nvarchar(50));
insert into @data values (1, 'Test record 1');
insert into @data values (2, 'Test record 2');

declare @joined table (Id int, Name nvarchar(50), OptionalFieldName nvarchar(50), OptionalFieldValue nvarchar(50));
insert into @joined
select
data.Id
,data.Name
,opt.Name
,opt.Value
from @data data
inner join @optionalFields opt on data.Id = opt.ParentId

declare @cols as nvarchar(max);
set @cols = stuff((select distinct ',' + quotename(OptionalFieldName)
from @joined
for xml path(''), type).value('.', 'nvarchar(max)'), 1, 1, '');

select * into #tmp from @joined

DECLARE @query AS NVARCHAR(MAX)

set @query = 'SELECT Id, Name,' + @cols + '
from
(
select Id
,Name
,OptionalFieldName
,OptionalFieldValue
from #tmp
) x
pivot
(
max(OptionalFieldValue)
for OptionalFieldName in (' + @cols + ')
) p '

execute(@query);

See Demo 。两个版本似乎都给出了您所请求的结果。

关于sql-server - 不聚合的旋转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36295394/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com