【发布时间】:2012-09-23 16:10:10
【问题描述】:
我需要一些帮助来将数据行转换为列。
我的每一行包含 8 列,我希望将所有这些列都包含在最终的列列表中。
通常,我会编写如下所示的 select 语句来返回与特定 ProductID 相关的所有定价行(大约 11 个)
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)
【问题讨论】:
-
我不确定在这种情况下,pivot 将如何工作,因为我没有预定义的范围或值来预期原始 select 语句的每一列中的值。
标签: sql sql-server pivot