我需要一些帮助来将数据行转换为列。
我的每一行都包含 8 列,我希望将所有这些列都包含在最终的列列表中。
通常,我会编写一个如下所示的 select 语句,以返回与特定产品相关的所有定价行(大约 11 个)ProductID
SELECT
ProductID,
PricingID,
COSBeginQty ,
COSCOLCode,
COSTrade,
COSTypeOfPrice,
COSIsActive,
COSPrice,
COSPriceTAG,
RowIndex
FROM
Pricing
Where
ProductID = XXXXX
我返回的每一行都有关于我想要显示所有返回值的内容:
ProductID,
CosBeginQty1 COSBeginQty1 COSCOLCode1 COSTrade1 COSTypeOfPrice1 COSIsActive1 COSPrice1 COSPriceTAG1
CosBeginQty2 COSBeginQty2 COSCOLCode2 COSTrade2 COSTypeOfPrice2 COSIsActive2 COSPrice2 COSPriceTAG2
CosBeginQty3, COSBeginQty3 COSCOLCode3 COSTrade3 COSTypeOfPrice3 COSIsActive3 COSPrice3 COSPriceTAG3 . . . .
. . .(从所有 11 行中计算我需要的值,总共 89 列)
这是我桌子上的脚本
CREATE TABLE [dbo].[Pricing](
[ProductID] [uniqueidentifier] NOT NULL,
[PricingID] [uniqueidentifier] NULL,
[COSBeginQty] [int] NULL,
[COSCOLCode] [nvarchar](50) NULL,
[COSTrade] [nvarchar](50) NULL,
[COSTypeOfPrice] [nchar](10) NULL,
[COSIsActive] [bit] NULL,
[COSPrice] [decimal](12, 3) NULL,
[COSPriceTAG] [uniqueidentifier] NULL,
[RowIndex] [int] NULL,
[COSCreateDate] [datetime] NULL,
[COSLastModifiedDate] [datetime] NULL,
CONSTRAINT [PK_Pricing] PRIMARY KEY CLUSTERED
(
[ProductID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
INSERT [dbo].[Pricing] ([ProductID], [PricingID], [COSBeginQty], [COSCOLCode], [COSTrade], [COSTypeOfPrice], [COSIsActive], [COSPrice], [COSPriceTAG], [RowIndex], [COSCreateDate], [COSLastModifiedDate]) VALUES (N'99533f6e-218f-48ef-bf01-03ea7808f9b1', N'5d8de11a-2399-4c68-87cd-4969827bed27', 7, N'MAN', N'T1', N'B ', 1, CAST(23.400 AS Decimal(12, 3)), N'bf1d79bf-a60d-4603-8c2d-04492e9e1575', 1, NULL, NULL)
GO
INSERT [dbo].[Pricing] ([ProductID], [PricingID], [COSBeginQty], [COSCOLCode], [COSTrade], [COSTypeOfPrice], [COSIsActive], [COSPrice], [COSPriceTAG], [RowIndex], [COSCreateDate], [COSLastModifiedDate]) VALUES (N'94d67d13-e4e6-4360-9b7a-1cef7d997297', N'5ba0a6e9-53ed-4b9c-a9eb-2b09c41eb56c', 2, N'MAN', N'T2', N'A ', 1, CAST(3456.234 AS Decimal(12, 3)), N'6ce7d421-e49a-469f-ae4c-a8bbb2f432fc', 3, NULL, NULL)
GO
INSERT [dbo].[Pricing] ([ProductID], [PricingID], [COSBeginQty], [COSCOLCode], [COSTrade], [COSTypeOfPrice], [COSIsActive], [COSPrice], [COSPriceTAG], [RowIndex], [COSCreateDate], [COSLastModifiedDate]) VALUES (N'e2216b52-66a9-4c29-a8ec-83c6ae03cd18', N'a8c27e9a-120c-47f2-bdd9-3e9e934ca237', 12, N'TEM', N'T1', N'B ', 1, CAST(7234.000 AS Decimal(12, 3)), N'555c0f25-6af9-4114-8f11-096f0e5c7bcd', 1, NULL, NULL)
GO
ALTER TABLE [dbo].[Pricing] ADD CONSTRAINT [DF_Pricing_ProductID] DEFAULT (newid()) FOR [ProductID]
GO
ALTER TABLE [dbo].[Pricing] ADD CONSTRAINT [DF_Pricing_PricingID] DEFAULT (newid()) FOR [PricingID]
GO
ALTER TABLE [dbo].[Pricing] ADD CONSTRAINT [DF_Pricing_COSPriceTAG] DEFAULT (newid()) FOR [COSPriceTAG]
GO
问题的解决方案如下,感谢 BLUEFEET
select *, row_number() over(partition by ProductID order by ProductID) rn
from dbo.pricing;
DECLARE @colsUnpivot AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX),
@colsPivot as NVARCHAR(MAX)
select @colsUnpivot = stuff((select ','+quotename(C.name)
from sys.columns as C
where C.object_id = object_id('Pricing') and
C.name LIKE '%COS%'
and C.name Not in ('COSCreateDate', 'COSLastModifiedDate')
for xml path('')), 1, 1, '')
select @colsPivot = STUFF((SELECT ','
+ quotename(c.name
+ cast(t.rn as varchar(10)))
from
(
select row_number() over(partition by productid
order by productid) rn
from Pricing
) t
cross apply
sys.columns as C
where C.object_id = object_id('Pricing') and
C.name LIKE '%COS%'
and C.name Not in ('COSCreateDate', 'COSLastModifiedDate')
group by c.name, t.rn
order by t.rn
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query
= 'select *
from
(
select ProductID,
col + cast(rn as varchar(10)) new_col,
val
from
(
select ProductID,
PricingID,
cast(COSBeginQty as varchar(50)) COSBeginQty,
cast(COSCOLCode as varchar(50)) COSCOLCode,
cast(COSTrade as varchar(50)) COSTrade,
cast(COSTypeOfPrice as varchar(50)) COSTypeOfPrice,
cast(COSIsActive as varchar(50)) COSIsActive,
cast(COSPrice as varchar(50)) COSPrice,
cast(COSPriceTAG as varchar(50)) COSPriceTAG,
RowIndex,
row_number() over(partition by productid
order by productid) rn
from Pricing
) x
unpivot
(
val
for col in ('+ @colsunpivot +')
) u
) x1
pivot
(
max(val)
for new_col in
('+ @colspivot +')
) p'
exec(@query)