sqlserver行转列转化实例

本文介绍了如何在SQL Server中将数据表的行转换为列,通过一组核心函数实现动态列的转换。适用于初学者,提供了具体的使用公式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以下为实现了数据表行转列,并实现动态列:

-- =============================================
-- Author:		<Author,,Name>
-- Create date: <Create Date,,>
-- Description:	<Description,,>
-- =============================================
ALTER PROCEDURE PROC_BI_XDHPZLGL (
 @P_WLCODE VARCHAR(MAX),
 @P_JYTYPE VARCHAR(20),
 @P_BEGINDATE VARCHAR(8),
 @P_ENDDATE VARCHAR(8)
)
AS
BEGIN
--建立明细数据结果集的临时表
DECLARE @V_SQL NVARCHAR(MAX);
DECLARE @V_SQL_01 NVARCHAR(300);
DECLARE @V_SQL_02 NVARCHAR(300);
DECLARE @V_SQL_03 NVARCHAR(300);

--检验类型条件处理
 IF @P_JYTYPE=0 BEGIN SET @V_SQL_01=' and A.ZLYWBG1_LYLX=0' END
 IF @P_JYTYPE=1 BEGIN SET @V_SQL_01=' and A.ZLYWBG1_LYLX=1'  END
 IF @P_JYTYPE=2 BEGIN SET @V_SQL_01=' and A.ZLYWBG1_LYLX=2'  END
 IF @P_JYTYPE=3 BEGIN SET @V_SQL_01=' and A.ZLYWBG1_LYLX=3'  END
 IF @P_JYTYPE=9 BEGIN SET @V_SQL_01=' and A.ZLYWBG1_LYLX=9'  END
 IF @P_JYTYPE=99 BEGIN SET @V_SQL_01=' '; END
   --	0,到货检验;1,留样检验;2,复检检验;3,有效期检验;9,退货检验
--报告日期条件处理
SET @V_SQL_02=' and A.ZLYWBG1_BGRQ>='+@P_BEGINDATE;
SET @V_SQL_03=' and A.ZLYWBG1_BGRQ<='+@P_ENDDATE;
IF @P_BEGINDATE='' OR LEN(@P_BEGINDATE)=0 BEGIN set @V_SQL_02=' '  END
IF @P_ENDDATE=''   OR LEN(@P_ENDDATE)=0   BEGIN set @V_SQL_03=' '  END
--物料编号条件处理
set @P_WLCODE=''''+replace(@P_WLCODE,'','''')+'''';
set @P_WLCODE=REPLACE(@P_WLCODE,',',''',''');
--结果集
SET @V_SQL='SELECT
	A.ZLYWBG1_LSBH 流水编号,
	A.ZLYWBG1_GSID 核算单位,
	D.MaterialCode 物料编号,
	D.MaterialName 物料名称,
	A.ZLYWBG1_C1  规格,
	A.ZLYWBG1_PCH 批号,
	A.ZLYWBG1_SXRQ 有效期,
	A.ZLYWBG1_BJSL 检验数量,
	A.ZLYWBG1_C3 留样观察方案,
	A.ZLYWBG1_C4 观察周期,
	'' '' 计划考察日期,
	A.ZLYWBG1_BGRQ 考察时间,
	B.ZLYWBG2_FLBH 分录流水,
	A.ZLYWBG1_JYYJ 检验依据,
	C.ZLJYXM_XMMC  检验项目,
    B.ZLYWBG2_JYJG 检验结果,
	A.ZLYWBG1_BGRS 考察人,
	A.ZLYWBG1_FHR 复核人,
	'' '' 原始记录单号,
	A.ZLYWBG1_BGRS 检验人,
	case when A.ZLYWBG1_HGBZ=''01'' then ''合格''
	 else ''不合格'' end as  是否合格,
	case when A.ZLYWBG1_BBH=''1'' then ''是'' 
	 else ''否'' end as 是否一等品,
	A.ZLYWBG1_SJDH 报告单号,
	A.ZLYWBG1_BGRQ 报告日期,
	A.ZLYWBG1_BZ 备注
FROM
	ZLYWBG1 A
LEFT JOIN ZLYWBG2 B ON A.ZLYWBG1_LSBH = B.ZLYWBG2_LSBH
LEFT JOIN ZLJYXM  C  ON C.ZLJYXM_NM=B.ZLYWBG2_XMBH
left join Materials D ON D.MaterialID=A.ZLYWBG1_JYWL
WHERE  C.ZLJYXM_XMMC!='''' AND D.MaterialCode  in ('+@P_WLCODE+')';
SET @V_SQL=@V_SQL+@V_SQL_01+@V_SQL_02+@V_SQL_03;
PRINT(@V_SQL);

--建立临时表
declare @v_sqlstr nvarchar(max);
drop table XDHP_ZLGL;
set @v_sqlstr='select * into XDHP_ZLGL from ('+@v_sql+') as A';
exec(@v_sqlstr);

--进行列转行处理

DECLARE @sql_str NVARCHAR(MAX)
DECLARE @sql_col NVARCHAR(MAX)
DECLARE @tableName SYSNAME       --需要行转列表的表名(或者视图、临时表)
DECLARE @groupColumn SYSNAME     --分组字段
DECLARE @row2column SYSNAME      --行变列的字段
DECLARE @row2columnValue SYSNAME --行变列值的字段
SET @tableName = 'XDHP_ZLGL'
SET @groupColumn = '物料编号,物料名称,规格,批号,有效期,检验数量,留样观察方案,观察周期,计划考察日期,考察时间,检验依据,考察人,复核人,原始记录单号,检验人,是否合格,是否一等品,报告单号,报告日期,备注'
SET @row2column = '检验项目'
SET @row2columnValue = '检验结果'

--从行数据中动态获取列
SET @sql_str = N'
SELECT @sql_col_out = ISNULL(@sql_col_out + '','','''') + QUOTENAME('+@row2column+') 
    FROM '+@tableName+' GROUP BY '+@row2column
PRINT @sql_str
EXEC sp_executesql @sql_str,N'@sql_col_out NVARCHAR(MAX) OUTPUT',@sql_col_out=@sql_col OUTPUT
PRINT @sql_col

SET @sql_str = N'
SELECT * FROM (
    SELECT '+@groupColumn+','+@row2column+','+@row2columnValue+' FROM '+@tableName+') p PIVOT 
    (max('+@row2columnValue+') FOR '+@row2column+' IN ( '+ @sql_col +') ) AS pvt 
ORDER BY '+@groupColumn+''
PRINT (@sql_str)
EXEC (@sql_str)
END

 

行转列的核心:

SET @sql_str = N'
SELECT * FROM (
    SELECT '+@groupColumn+','+@row2column+','+@row2columnValue+' FROM '+@tableName+') p PIVOT 
    (max('+@row2columnValue+') FOR '+@row2column+' IN ( '+ @sql_col +') ) AS pvt 
ORDER BY '+@groupColumn+''
PRINT (@sql_str)
EXEC (@sql_str)

其中 

@groupColumn         : 需要分组的字段

@row2column           :可以进行聚合函数的字段(max,sum等)

@row2columnValue  :需要进行转列的字段

固定搭配,初学者可以当做公式使用(在sqlserver数据库中适用)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值