使用枢轴转换表:将行选择为列

时间:2019-12-14 19:38:35

标签: sql sql-server pivot

我的数据需要按以下方式转移:

Before & After

我一直在努力使用存储过程方法,使用临时表将SKU分组,然后构建输出,但是速度非常慢。现在,我刚刚找到了PIVOT关键字。如果有人可以向我展示如何使用PIVOT进行转换,我将不胜感激。

请注意,奋斗之处在于FeeName列,因为它的值成为结果中新的三列(目前)。

创建表格:

USE [Test];
GO

SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO
CREATE TABLE [dbo].[Order]
(
    [Id] [UNIQUEIDENTIFIER] NOT NULL,
    [OrderId] [INT] NOT NULL,
    [FeeName] [VARCHAR](25) NOT NULL,
    [Amount] [MONEY] NOT NULL,
    [SKU] [INT] NOT NULL,
    [Description] [VARCHAR](100) NOT NULL,
    CONSTRAINT [PK_Order_Id]
        PRIMARY KEY CLUSTERED ([Id] ASC)
        WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
              ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF
             ) ON [PRIMARY]
) ON [PRIMARY];
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'ce62e8a8-6650-4466-b629-086cc5b5db79', 12346, N'Item Fee', 100.0000, 789, N'Third')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'3229c09d-9562-4497-811e-0e0c2da022bc', 12347, N'Item Fee', 100.0000, 123, N'First')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'dc97d7c3-f31b-422e-be50-1197d67becdd', 12345, N'Commission', 125.0000, 789, N'Third')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'c8951c07-1070-4962-b4e4-1890d8cbc767', 12345, N'Penalty', 150.0000, 123, N'First')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'4faf4cf1-18ef-4fbe-bb13-19345575d981', 12346, N'Penalty', 150.0000, 123, N'First')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'03ae5fc7-8df2-4ea1-9186-1dc710d21d96', 12345, N'Penalty', 150.0000, 456, N'Second')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'a19a57ed-f56c-443b-8694-2c262bf40fb0', 12346, N'Penalty', 150.0000, 789, N'Third')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'5cac38cd-6e49-4d50-b644-2e42cff6faa3', 12346, N'Commission', 125.0000, 123, N'First')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'f5909f7c-54da-49aa-a0e9-4123a404a8ff', 12347, N'Penalty', 150.0000, 456, N'Second')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'1b821e19-781c-4ca3-ba7d-41e8a0ef10c2', 12346, N'Item Fee', 100.0000, 123, N'First')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'f005fdc1-04e5-4bdc-9b89-433589ed8e39', 12346, N'Penalty', 150.0000, 456, N'Second')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'77800636-35bd-4528-8171-4ae44c9edf14', 12345, N'Item Fee', 100.0000, 456, N'Second')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'120a6dd8-75a5-4c03-a319-511a137ea2f1', 12345, N'Penalty', 150.0000, 789, N'Third')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'589d0383-f2f7-475c-b84f-56dda1561a8f', 12345, N'Commission', 125.0000, 456, N'Second')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'3322b7a2-8173-470b-a92b-5b9edbddcd69', 12345, N'Item Fee', 100.0000, 790, N'Fourth')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'4aeb5d9e-0e8a-4111-a81d-65cccba9cd28', 12345, N'Commission', 125.0000, 790, N'Fourth')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'fbc02e3c-db5a-4e1a-bf28-6878ca244fc4', 12345, N'Item Fee', 100.0000, 789, N'Third')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'9050d591-5ddd-44a8-a752-69a3ee0e3a87', 12347, N'Commission', 125.0000, 123, N'First')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'239ebb6c-adb9-4946-a9a1-760f5cf6ec00', 12347, N'Commission', 125.0000, 456, N'Second')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'0ef5aa3f-f300-4498-b883-775187a2fc67', 12345, N'Penalty', 150.0000, 790, N'Fourth')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'9e4dcf8e-e49d-429e-8d05-a315567e9562', 12347, N'Penalty', 150.0000, 123, N'First')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'fa82700d-6dc8-4765-921a-ad38bb2e7f3b', 12346, N'Commission', 125.0000, 789, N'Third')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'84a9cfac-0c10-4c33-b04b-b66b3c4f53a2', 12346, N'Commission', 125.0000, 456, N'Second')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'b6e8ded6-43ee-4e67-8c53-b7da2a8f2141', 12347, N'Penalty', 150.0000, 789, N'Third')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'95867794-1fbb-455e-ab94-d37fcda499af', 12347, N'Item Fee', 100.0000, 789, N'Third')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'64f3ecc6-0a43-4204-b5b0-dd1dd21e1eb2', 12346, N'Item Fee', 100.0000, 456, N'Second')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'647f63c3-d2ba-4fc1-9169-e5525db9d4d9', 12345, N'Commission', 125.0000, 123, N'First')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'd4115a4e-a149-4a0b-89a6-f4cfdaf8f57f', 12347, N'Item Fee', 100.0000, 456, N'Second')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'd93a6e0f-f6ce-4d29-8894-fb0d858d4095', 12347, N'Commission', 125.0000, 789, N'Third')
GO

INSERT [dbo].[Order] ([Id], [OrderId], [FeeName], [Amount], [SKU], [Description]) VALUES (N'12e3df48-f63f-4e1e-b87e-fc4da7c30eac', 12345, N'Item Fee', 100.0000, 123, N'First')
GO

ALTER TABLE [dbo].[Order] ADD  CONSTRAINT [DF_Order_Id]  DEFAULT (newid()) FOR [Id]
GO

ALTER TABLE [dbo].[Order] ADD  CONSTRAINT [DF_Order_Amount]  DEFAULT ((0)) FOR [Amount]
GO

2 个答案:

答案 0 :(得分:1)

您的屏幕截图(“商品信用”)与示例数据(“商品费用”)之间存在差异,由于您在以下位置重复使用了相同的Amount,因此很难看到结果结束,但是我想这就是您想要的:

select OrderId, [Item Fee], [Commission], [Penalty], SKU, Description
from 
(
    select OrderId, FeeName, Amount, SKU, Description from [Order]
) as src
pivot
(
    max(Amount)
    for FeeName in ([Item Fee], [Commission], [Penalty])
) piv;

答案 1 :(得分:1)

我建议为此使用条件聚合。与pivot的特定于供应商的实现不同,这是一种适用于大多数(如果不是全部)RDBMS的标准技术。而且,它通常比特定的实现(通常依赖于幕后的条件聚合)更快甚至更快。

select
    OrderID,
    max(case when FeeName = 'Item' Credit' then Amount end) [Item Credit],
    max(case when FeeName = 'Commission' then Amount end) [Commission],
    max(case when FeeName = 'Penalty' then Amount end) [Penalty],
    SKU,
    Description
from [Order]
group by 
    OrderID,
    SKU,
    Description
order by 
    OrderID,
    SKU,
    Description

Demo on DB Fiddle with your sample data

OrderID | Item Fee | Commission | Penalty  | SKU | Description
------: | :------- | :--------- | :------- | --: | :----------
  12345 | 100.0000 | 125.0000   | 150.0000 | 123 | First      
  12345 | 100.0000 | 125.0000   | 150.0000 | 456 | Second     
  12345 | 100.0000 | 125.0000   | 150.0000 | 789 | Third      
  12345 | 100.0000 | 125.0000   | 150.0000 | 790 | Fourth     
  12346 | 100.0000 | 125.0000   | 150.0000 | 123 | First      
  12346 | 100.0000 | 125.0000   | 150.0000 | 456 | Second     
  12346 | 100.0000 | 125.0000   | 150.0000 | 789 | Third      
  12347 | 100.0000 | 125.0000   | 150.0000 | 123 | First      
  12347 | 100.0000 | 125.0000   | 150.0000 | 456 | Second     
  12347 | 100.0000 | 125.0000   | 150.0000 | 789 | Third