循环、行列转换、跨表更新的综合案列

一、背景

1.1 数据库

SQL SERVER 数据库

 

1.2 场景说明

当需要对每批次,月,日或者其他可以按照数字排序的结果说明;

结果是数字,但是每个数字代表的含义不同

 

1.3 建表

CREATE TABLE [cnblogs].[pivot_t] (
  [姓名] nvarchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
  [批次] int  NULL,
  [结果] int  NULL
)  

 

CREATE TABLE [cnblogs].[pivot_id] (
  [id] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
  [说明] nvarchar(255) COLLATE Chinese_PRC_CI_AS  NULL
)  

 

1.4 插入数据

INSERT INTO [cnblogs].[pivot_t]([姓名], [批次], [结果]) VALUES (N'张三', 1, 4);
INSERT INTO [cnblogs].[pivot_t]([姓名], [批次], [结果]) VALUES (N'张三', 2, 3);
INSERT INTO [cnblogs].[pivot_t]([姓名], [批次], [结果]) VALUES (N'张三', 3, 1);
INSERT INTO [cnblogs].[pivot_t]([姓名], [批次], [结果]) VALUES (N'张三', 4, 5);
INSERT INTO [cnblogs].[pivot_t]([姓名], [批次], [结果]) VALUES (N'张三', 5, 2);
INSERT INTO [cnblogs].[pivot_t]([姓名], [批次], [结果]) VALUES (N'张三', 6, 1);
INSERT INTO [cnblogs].[pivot_t]([姓名], [批次], [结果]) VALUES (N'李四', 1, 1);
INSERT INTO [cnblogs].[pivot_t]([姓名], [批次], [结果]) VALUES (N'李四', 2, 3);
INSERT INTO [cnblogs].[pivot_t]([姓名], [批次], [结果]) VALUES (N'李四', 3, 5);
INSERT INTO [cnblogs].[pivot_t]([姓名], [批次], [结果]) VALUES (N'李四', 4, 2);
INSERT INTO [cnblogs].[pivot_t]([姓名], [批次], [结果]) VALUES (N'李四', 5, 4);
INSERT INTO [cnblogs].[pivot_t]([姓名], [批次], [结果]) VALUES (N'李四', 6, 2);

 

INSERT INTO [cnblogs].[pivot_id]([id], [说明]) VALUES ('1', N'微信支付');
INSERT INTO [cnblogs].[pivot_id]([id], [说明]) VALUES ('2', N'支付宝支付');
INSERT INTO [cnblogs].[pivot_id]([id], [说明]) VALUES ('3', N'财付通支付');
INSERT INTO [cnblogs].[pivot_id]([id], [说明]) VALUES ('4', N'点券支付');
INSERT INTO [cnblogs].[pivot_id]([id], [说明]) VALUES ('5', N'支付失败');

 

1.5 目的

 

 

 

 

 

二、建立存储过程

USE [test]
GO
/****** Object:  StoredProcedure [cnblogs].[行列转换]    Script Date: 2022/3/6 16:09:38 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO


create  PROCEDURE [cnblogs].[行列转换]
AS 
BEGIN


drop table if exists #pivot;                            -- 更改批次值,批次值会变成列名;
select 姓名,CONCAT('t',批次) as 批次,cast(结果 as int) as 结果 into #pivot from test.cnblogs.pivot_t   -- 聚合的部分必须是数字
;

drop table if exists #pivot_table;                      -- 完成行列转换
SELECT * INTO #pivot_table
FROM
(
SELECT * FROM #pivot AS P
PIVOT(sum(结果) FOR 批次 in ([t1],[t2],[t3],[t4],[t5],[t6])) AS T
) AS t1



/*
对结果含义进行更新,由数字转换为文字
因为进行行列转换之后多出来6列,所以进行循环
*/
declare @start_num int ;
declare @cl_name varchar(20);
declare @alter_sql varchar(MAX);
declare @update_sql varchar(MAX);
set @start_num = 1 ;
WHILE (@start_num<= 6)
    BEGIN
    set @cl_name = CONCAT('t',cast(@start_num as varchar));                                    -- 取列名
    set @alter_sql = 'ALTER TABLE #pivot_table ALTER COLUMN ['+ @cl_name + '] varchar(20)';    -- 将列调整为字符串格式
    set @update_sql = 'UPDATE A SET A.['+ @cl_name + '] = B.[说明] FROM #pivot_table as A, test.cnblogs.pivot_id as B where A.['+ @cl_name + ']=B.[id] '; -- 跨表更新
    exec (@alter_sql);                                                                        -- 执行更改格式命令
    exec (@update_sql);                                                                       -- 执行更新命令 
    set @start_num = @start_num+1                                                             -- 准备对下一列执行处理
    END



;
drop table if exists test.dbo.pivot_result                             
SELECT * 
INTO test.dbo.pivot_result
FROM #pivot_table
;


END

 

 

三、查看结果

 

posted @ 2022-03-06 16:14  qsl_你猜  阅读(61)  评论(0编辑  收藏  举报