Dynamic Pivot table wizard SQL Server

本文涉及的产品
云数据库 RDS SQL Server,独享型 2核4GB
简介: 原文 http://www.gyurcit.hu/pivot.html Dynamic Pivot table wizard This stored procedure generate dynamic crosstable with multiple pivot columns by 4+1 parameters.

原文 http://www.gyurcit.hu/pivot.html

Dynamic Pivot table wizard

This stored procedure generate dynamic crosstable with multiple pivot columns by 4+1 parameters.

 

 

1. P_Row_Field Name of field that reperesent the spreadsheet's rows
2. P_Column_Field Name of field that store the name of columns
3. P_Value Name of field that represent the spreedsheet's value
4. P_From Name of source table
5. P_Where Filter expression (optional)


Values of second parameter field should not include apastrophe.  Procedure does not check paramaters (you must do that), so it may causes sql injection attack.

To source code click one of them

 

 
-- =================================================
-- Pivot Table Wizard            (c) 2009 by GyurcIT
-- http://www.gyurcit.hu   e-mail: gyurcit@gmail.com
-- =================================================

IF EXISTS (SELECT name FROM sysobjects
           WHERE  name = N'PivotWizard' AND type = 'P')
    DROP PROCEDURE PivotWizard
GO
-----------------------------------------------------
-----------------------------------------------------
CREATE PROCEDURE PivotWizard
   @P_Row_Field    VARCHAR(255),
   @P_Column_Field VARCHAR(255),
   @P_Value        VARCHAR(255),
   @P_From         VARCHAR(4000),
   @P_Where        VARCHAR(4000) = '1=1'
AS

  DECLARE @SQL NVARCHAR(4000)

  -- Build SQL statment that upload @Columns string 
  -- with @P_Column_Filed values
  CREATE TABLE #TEMP  (ColumnField varchar(100))
  SET @sql ='SELECT DISTINCT '+@P_Column_Field+' AS ColumnField'+
              ' FROM '+@P_From+
              ' WHERE '+@P_Where+
              ' ORDER BY '+@P_Column_Field
  INSERT INTO #TEMP
  EXEC(@sql)
  PRINT @sql

  -- Check count of columns
  DECLARE @Count_Columns int
  SELECT @Count_Columns = COUNT(*) FROM #Temp
  IF (@Count_Columns<1) OR (@Count_Columns>255)  BEGIN
      DROP TABLE #Temp
      RAISERROR('%d is invalid columns amount. Valid is 1-255',
16,1,@Count_columns)
      RETURN
  END
  -- Upload @Columns from #Temp
  DECLARE @Columns VARCHAR(8000),
          @Column_Field VARCHAR(8000)

  SET @Columns = ''
  DECLARE Column_cursor CURSOR LOCAL FOR
  SELECT CAST(ColumnField AS VARCHAR(60))
  FROM #Temp
  OPEN Column_cursor
  FETCH NEXT FROM Column_cursor
  INTO @Column_Field
  WHILE @@FETCH_STATUS = 0 BEGIN
      SET @Columns = @Columns +
        ' SUM('+
             ' CASE WHEN '+@P_Column_Field+'='''+ @Column_Field+''''+
             ' THEN '+@P_Value+
             ' ELSE 0 END'+
             ') AS ['+ @Column_Field +'], '
      FETCH NEXT FROM Column_cursor
      INTO @Column_Field
  END
  CLOSE Column_cursor
  DEALLOCATE Column_cursor
  DROP TABLE #Temp

  IF @Columns='' RETURN 1
  SET @Columns = Left(@Columns,Len(@Columns)-1)

  -- Build Pivot SQL statment
  DECLARE @Pivot_SQL VARCHAR(8000)
  SET @Pivot_SQL =              'SELECT '  +@P_Row_Field+', '+@Columns
  SET @Pivot_SQL = @Pivot_SQL +' FROM '    +@P_From
  SET @Pivot_SQL = @Pivot_SQL +' WHERE '   +@P_Where
  SET @Pivot_SQL = @Pivot_SQL +' GROUP BY '+@P_Row_Field
  SET @Pivot_SQL = @Pivot_SQL +' ORDER BY '+@P_Row_Field
  SET @Pivot_SQL = @Pivot_SQL + '#'

  IF Right(@Pivot_SQL,1)<>'#'
  BEGIN
     RAISERROR('SQL statement is too long. It must be less
                than 8000 charachter!',16,1)
     RETURN 1
  END
  SET @Pivot_SQL = Left(@Pivot_SQL,Len(@Pivot_SQL)-1)

  -- PRINT @Pivot_SQL
  EXEC(@Pivot_SQL)

  RETURN 0
GO

-- Example use Northwind database --
-- Example 1 --
exec PivotWizard 'ShipCountry',
                 'YEAR(OrderDate)*100+Month(OrderDate)',
                 '[ExtendedPrice]',
                 'dbo.Invoices',
                 'OrderDate BETWEEN ''1996/01/01'' and ''1996/12/31'''

GO

-- Example 2 --
exec PivotWizard 'ProductName',
                 'ShipCountry',
                 '[ExtendedPrice]',
                 'dbo.Invoices',
                 'OrderDate BETWEEN ''1996/01/01'' and ''1996/12/31'''

-- =================================================
-- Pivot Table Wizard MySQL      (c) 2009 by GyurcIT
-- http://www.gyurcit.hu   e-mail: gyurcit@gmail.com
-- =================================================
-- USE Database
DROP PROCEDURE IF EXISTS pivotwizard;

CREATE DEFINER = 'root'@'192.168.1.119'
PROCEDURE pivotwizard(
   IN P_Row_Field    VARCHAR(255),
   IN P_Column_Field VARCHAR(255),
   IN P_Value        VARCHAR(255),
   IN P_From         VARCHAR(4000),
   IN P_Where        VARCHAR(4000))
BEGIN
 DECLARE done INT DEFAULT 0;
 DECLARE M_Count_Columns int DEFAULT 0;
 DECLARE M_Column_Field varchar(60);
 DECLARE M_Columns VARCHAR(8000) DEFAULT '';
 DECLARE M_sqltext VARCHAR(8000);
 DECLARE M_stmt VARCHAR(8000);
 DECLARE cur1 CURSOR FOR SELECT CAST(Column_Field AS CHAR) FROM Temp;
 DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

 DROP TABLE IF EXISTS Temp;
 SET @M_sqltext = CONCAT('CREATE TEMPORARY TABLE Temp ',
                   ' SELECT DISTINCT ',P_Column_Field, 
				' AS Column_Field',
                   ' FROM ',P_From,
                   ' WHERE ',P_Where,
                   ' ORDER BY ', P_Column_Field);

 PREPARE M_stmt FROM @M_sqltext;
 EXECUTE M_stmt;

 SELECT COUNT(*) INTO M_Count_Columns 
 FROM Temp 
 WHERE Column_Field IS NOT NULL;

 IF (M_Count_Columns > 0) THEN
    OPEN cur1;
    REPEAT
      FETCH cur1 INTO M_Column_Field;
      IF (NOT done) and (M_Column_Field IS NOT NULL) THEN
         SET M_Columns = CONCAT(M_Columns,
' SUM( CASE WHEN ',P_Column_Field,'=''',M_Column_Field,'''',
         		' THEN ',P_Value,
                  ' ELSE 0 END) AS `', M_Column_Field ,'`,');

      END IF;
    UNTIL done END REPEAT;
    SET M_Columns = Left(M_Columns,Length(M_Columns)-1);
    SET @M_sqltext = CONCAT('SELECT ',P_Row_Field,',',M_Columns,
                            ' FROM ', P_From,
                            ' WHERE ', P_Where,
                            ' GROUP BY ', P_Row_Field,
                            ' ORDER BY ', P_Row_Field);

    PREPARE M_stmt FROM @M_sqltext;
    EXECUTE M_stmt;
  END IF;
END
-- Example:
CALL pivotwizard('article','Month(date)',
'netto',
'invoice',
'(year(date)=2009)')
 
 

 

 
相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS&nbsp;SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/sqlserver
目录
相关文章
|
存储 SQL
sql server 存储过程传递表名参数及Dynamic SQL
sql server 存储过程传递表名参数及Dynamic SQL
sql server 存储过程传递表名参数及Dynamic SQL
|
SQL Java 数据库连接
Data Access 之 MyBatis(四) - Dynamic SQL(下)
Data Access 之 MyBatis(四) - Dynamic SQL
Data Access 之 MyBatis(四) - Dynamic SQL(下)
|
SQL Java 数据库连接
Data Access 之 MyBatis(四) - Dynamic SQL(上)
Data Access 之 MyBatis(四) - Dynamic SQL
Data Access 之 MyBatis(四) - Dynamic SQL(上)
使用CL_RS_WHERE创建dynamic SQL statement
使用CL_RS_WHERE创建dynamic SQL statement
使用CL_RS_WHERE创建dynamic SQL statement
One order search dynamic sql statement生成位置
One order search dynamic sql statement生成位置
One order search dynamic sql statement生成位置
|
SQL Java 数据库连接
Can I use MyBatis to generate Dynamic SQL without executing it?
Although MyBatis was designed to execute the query after it builds it, you can make use of it's configuration and a little bit of "inside knowledge" to get to what you need.
1310 0
|
SQL 大数据 API
Flink Table/SQL API 规划 —— Dynamic Table
动态表直观上看是一个类似于数据库中的`Materialized View`概念。动态表随着时间改变;类似静态的batch table一样可以用标准SQL进行查询然后一个新的动态表;可以和流无损地互相转换(对偶的)。
10216 0