`
xiaoer_1982
  • 浏览: 1865263 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

再议PIVOT语句的一个注意点和一个问题的扩展

阅读更多

再议PIVOT语句的一个注意点和一个问题的扩展

问题引入:

刚才和小梁在讨论PIVOT语句行转列后的一个求和问题,结果在解决的过程中带出一个新问题来,容再下慢慢道来。

环境准备:

------------------------------------------------------------------------

-- Author: happyflystone

-- Date : 2009-03-07 20:36:05

-- Ver: Microsoft SQL Server 2005 - 9.00.2047.00 (Intel X86)

-- Apr 14 2006 01:12:25

-- Copyright (c) 1988-2005 Microsoft Corporation

-- Standard Edition on Windows NT 5.0 (Build 2195: Service Pack 4)

--

------------------------------------------------------------------------

CREATE TABLE ta(id INT,col1 Nvarchar(2),col2 Nvarchar(2),col3 Nvarchar(8),col4 INT)

;

INSERT INTO ta

SELECT 1,'HN','CS','abc',1 UNION ALL

SELECT 2,'HN','CS','abcd',2 UNION ALL

SELECT 3,'HN','CD','abcd',3 UNION ALL

SELECT 4,'HN','HY','aa' ,4

要求结果:

COL1 COL2 abc abcd ae sum_

---- ---- ----------- ----------- ----------- -----------

HN CD NULL 3 NULL 3

HN CS 1 2 NULL 3

HN HY NULL NULL 4 4

实现:

DECLARE @s varchar(8000) ,@s1 varchar(8000)

SELECT @S = ISNULL(@S + ',','')+ '['+LTRIM(COL3)+']'

FROM (SELECT DISTINCT COL3 FROM ta) A

SELECT @S1 = ISNULL(@S1 + '+','')+ 'isnull(['+LTRIM(COL3)+'],0)'

FROM (SELECT DISTINCT COL3 FROM ta) A

EXEC('WITH T

AS

(SELECT COL1,COL2,'+@S+'

FROM

(SELECT COL1,COL2,COL3,COL4

FROM TA

) P

PIVOT

( SUM (COL4)

FOR COL3 IN ('+@S+')

)AS UNPVT)

SELECT *,'+@S1+' AS [SUM]

FROM T')

-- 小梁的解法

EXEC('SELECT COL1,COL2,'+@S+','+@s1+' as sum_

FROM

(SELECT COL1,COL2,COL3,COL4

FROM ta

) P

PIVOT

( SUM (COL4)

FOR COL3 IN ('+@S+')

)AS UNPVT')

set @s = null

--随手再写一个麻烦一点的

SELECT @S = ISNULL(@S + ',','')+ '['+LTRIM(COL3)+']'

FROM (SELECT DISTINCT COL3 FROM (SELECT COL1,COL2,COL3,COL4 FROM TA

UNION ALL

SELECT COL1,COL2 ,'SUM_' AS COL3,SUM(COL4) AS COL4 FROM TA GROUP BY COL1,COL2)B) A

EXEC('SELECT COL1,COL2,'+@S+'

FROM

(SELECT COL1,COL2,COL3,COL4

FROM (SELECT COL1,COL2,COL3,COL4 FROM TA

UNION ALL

SELECT COL1,COL2 ,''SUM_'' AS COL3,SUM(COL4) AS COL4

FROM TA

GROUP BY COL1,COL2)A

) P

PIVOT

( SUM (COL4)

FOR COL3 IN ('+@S+')

)AS UNPVT')

--结果显示

/*

COL1 COL2 abc abcd ae sum

---- ---- ----------- ----------- ----------- -----------

HN CD NULL 3 NULL 3

HN CS 1 2 NULL 3

HN HY NULL NULL 4 4

COL1 COL2 abc abcd ae sum_

---- ---- ----------- ----------- ----------- -----------

HN CD NULL 3 NULL 3

HN CS 1 2 NULL 3

HN HY NULL NULL 4 4

COL1 COL2 abc abcd ae SUM_

---- ---- ----------- ----------- ----------- -----------

HN CD NULL 3 NULL 3

HN CS 1 2 NULL 3

HN HY NULL NULL 4 4

*/

在上面的写法中所有SUM后面我都加了一个‘_’,一开始的出发点是怕关键字影响语句的执行,事实上没有'_'也不影响语句的执行和结果,大家可以测试一下,所以没去掉是为了说明下面我要说的一个注意点的引入,我在去掉'_'后发现不影响语句的执行和结果,心想如果COL3里有关键字是否影响语句的执行,于是又插入一行,INSERT INTO TA SELECT 5,'HN','HY','SUM' ,5,结果仍然没问题(大家自己测试,我不再列表了),心里乐呵呵,突然我决定加一个[sum]试试,奇怪的问题出现了

Delete from ta;

go

INSERT INTO ta

SELECT 1,'HN','CS','abc',1 UNION ALL

SELECT 2,'HN','CS','abcd',2 UNION ALL

SELECT 3,'HN','CD','abcd',3 UNION ALL

SELECT 4,'HN','HY','[sum]' ,4 -- 'sum]' 改成这样语法就过不了

DECLARE @s varchar(8000) ,@s1 varchar(8000)

SELECT @S = ISNULL(@S + ',','')+ '['+LTRIM(COL3)+']'

FROM (SELECT DISTINCT COL3 FROM ta) A

exec('SELECT COL1,COL2,'+@S+'

FROM

(SELECT COL1,COL2,COL3,COL4

FROM ta

) P

PIVOT

( SUM (COL4)

FOR COL3 IN ('+@S+')

)AS UNPVT')

--结果:

/*

COL1 COL2 [sum],[abc abcd

---- ---- ----------- -----------

HN CD NULL 3

HN CS NULL 2

HN HY NULL NULL

*/

晕,这是什么玩意呀,printSQL如下

SELECT COL1,COL2,[[sum]],[abc],[abcd]

FROM

(SELECT COL1,COL2,COL3,COL4

FROM ta

) P

PIVOT

( SUM (COL4)

FOR COL3 IN ([[sum]],[abc],[abcd])

)AS UNPVT

哦,原来]]转义了,这就是一个注意点:如果数据最后包含']'时使用PIVOT一定要注意哦,怎么解决呢,估计只能使用前先替代这个字符了,如果大家有好办法,希望告诉我,感谢!!

--删除测试环境:

drop table ta

分享到:
评论

相关推荐

    SQL Server 2005新功能之PIVOT的描述

    这样,原本需要通过CASE语句和聚合函数构造的复杂查询,现在只需要一条简单的PIVOT语句即可完成。这极大地提高了开发效率,也让查询代码更加简洁易懂。 需要注意的是,如果`column_to_pivot`列的值不确定,依然可以...

    SQL 2008行列转换的pivot

    根据给定的部分内容,我们可以看到一个具体的动态 SQL 实现 PIVOT 的例子。首先,创建了一个临时表 `#ABC` 并填充了一些示例数据。接下来,通过以下步骤实现了动态 PIVOT: 1. **获取所有可能的列值**:使用子查询 ...

    pivot-luke-5.5.0-luke-release.zip

    "pivot-luke-5.5.0-luke-release.zip" 是一个专门针对Lucene索引库的图形化界面工具,它的全称是Luke,由Java编写,就像数据库管理的得力助手Navicat一样,为Lucene用户提供了直观易用的操作界面。 Luke的主要功能...

    SQL聚集函数扩展.pdf

    PIVOT运算符可以将行数据转换为列,执行聚合操作,使得一个表中的行可以通过指定的列的唯一值转换成多个列,从而使数据的查看和分析更加直观。UNPIVOT则执行与PIVOT相反的操作,将列数据转换回行。 立方体操作...

    sql常用语句集锦 查询技巧

    例如,在一个循环更新操作中,可以检查`@@ROWCOUNT`来确定已处理了多少行。 5. **查询时间**: 查询时间相关的SQL语句,可能涉及到`DATEDIFF()`、`GETDATE()`和`BETWEEN`等函数。`DATEDIFF()`用来计算两个日期之间...

    经典SQL语句大全(值得一看)

    本资源"经典SQL语句大全"涵盖了基础到高级的多种SQL知识点,旨在帮助开发者和数据爱好者提升SQL技能,提高工作效率。 1. **SQL基础** - **数据查询**: 包括`SELECT`语句,用于从表中检索数据。基本形式如:`SELECT...

    SQL---行转列 详细描述

    下面将对这一知识点进行详细的解析。 ### SQL 行转列详解 #### 一、什么是行转列? 在数据库操作中,“行转列”(Pivot)是一种常见的数据变换需求。它指的是将原始数据表中的某些字段从行的形式转换为列的形式,...

    SSAS的扩展性、性能与优化

    SSAS(SQL Server Analysis Services)是微软提供的一个用于企业级数据仓库和商务智能的分析平台。它在处理大量数据和提供高效查询性能方面表现出色,同时也具有强大的扩展性,能够适应不断增长的数据需求。本篇文章...

    SQL Server里PIVOT运算符的”红颜祸水“

    例如,一个EAV表可能包含记录ID、元素(属性名)和值,用于存储如人名、城市等信息。查询这样的表时,需要将行数据转换为列,以便更直观地表示数据。 在不使用PIVOT运算符的情况下,可以手动实现这个转换。这通常...

    oracle 11g新特性

    假设有一个销售数据表,包含产品ID、销售日期和销售额,可以通过PIVOT操作符将按月份汇总的销售额转换成列的形式: ```sql SELECT * FROM sales PIVOT (SUM(sales) FOR EXTRACT(MONTH FROM sale_date) IN (1 AS 'Jan...

    PivotTable:从 MySQL 查询生成和呈现数据透视表

    这可以是简单的SELECT语句,或者更复杂的一系列JOIN和聚合函数,用于预处理数据。 ```php $sql = "SELECT column1, column2, SUM(column3) AS total FROM table GROUP BY column1, column2"; $result = $conn->...

    sql 教程和经典sql

    首先,"SQL参考手册.chm"可能是一个关于SQL语法和函数的综合指南,它通常包含以下内容: 1. **SQL基本概念**:介绍SQL的起源、用途以及关系数据库模型。 2. **数据操作语言(DML)**:包括INSERT、UPDATE、DELETE...

    期货指标大全汇总文华财经指标技术分析指标大全无未来函数逃顶抄底指标.doc

    这些数据用于计算枢轴点(PIVOT),枢轴点是技术分析中的一个重要概念,它代表了一个市场可能反转的位置,即支撑或阻力位。 PIVOT 的计算方法是取最高价、最低价和收盘价的平均值,然后用 LINETHICK2 标记出来。R1 ...

    Laravel开发-compoships

    在Laravel框架中,Compoships是一个非常有用的扩展,它扩展了Laravel的Eloquent ORM,使其能够处理复合键(也称为多键)的关系。在默认情况下,Laravel的Eloquent仅支持单一主键的关系,但许多实际数据库设计中,...

    SQL Server行转列使用

    这里,我们先创建了一个名为PivotData的CTE(公共表表达式),然后使用PIVOT将`Value1`和`Value2`转换为列。PIVOT内的MAX函数用于聚合每个ID下的值,IN关键字后的括号内定义了要转成列的值列表。 这两种方法各有优...

    2021-2022计算机二级等级考试试题及答案No.2795.docx

    3. 交叉表查询是为了解决一对多关系中,对"多方"实现分组求和的问题 - 交叉表查询(也称为Pivot查询)用于将行数据转换为列数据,通常用于分析和汇总数据,特别是在处理一对多关系时。 4. 查询各类商品的数量,正确...

    CSDN+Oracle版精华帖荟萃

    2. ORA-00904标识符无效:这是Oracle数据库中的一个常见错误,当SQL语句中使用了无效的标识符时,会引发此错误。解决这个问题通常需要检查SQL语句中的对象名(如表名、列名)是否拼写正确,以及是否在正确的模式...

    行列转换实例

    这里创建了一个名为`tb`的表,并插入了两组学生的成绩数据。 2. **实现静态SQL:** ```sql SELECT 姓名 AS 姓名, MAX(CASE 课程 WHEN '语文' THEN 分数 ELSE 0 END) 语文, MAX(CASE 课程 WHEN '数学' THEN ...

    oracle交叉表sql

    `:声明一个用于存储动态SQL语句的变量。 - `DECLARE done INT DEFAULT 0;`:声明一个控制循环的标志变量。 - `DECLARE StrSum Varchar(3000);`:声明一个用于存储求和表达式的变量。 - `DECLARE pCols Varchar...

    C#动态交叉表查询

    总的来说,C#动态交叉表查询是一个结合了数据处理、数据库操作和UI展示的综合性问题,理解和掌握这些知识点对于提升数据处理能力非常有帮助。无论是在报表开发、数据分析还是BI应用中,熟练运用动态交叉表都能让你的...

Global site tag (gtag.js) - Google Analytics