再议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
*/
晕,这是什么玩意呀,print出SQL如下 :
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
分享到:
相关推荐
这样,原本需要通过CASE语句和聚合函数构造的复杂查询,现在只需要一条简单的PIVOT语句即可完成。这极大地提高了开发效率,也让查询代码更加简洁易懂。 需要注意的是,如果`column_to_pivot`列的值不确定,依然可以...
根据给定的部分内容,我们可以看到一个具体的动态 SQL 实现 PIVOT 的例子。首先,创建了一个临时表 `#ABC` 并填充了一些示例数据。接下来,通过以下步骤实现了动态 PIVOT: 1. **获取所有可能的列值**:使用子查询 ...
"pivot-luke-5.5.0-luke-release.zip" 是一个专门针对Lucene索引库的图形化界面工具,它的全称是Luke,由Java编写,就像数据库管理的得力助手Navicat一样,为Lucene用户提供了直观易用的操作界面。 Luke的主要功能...
PIVOT运算符可以将行数据转换为列,执行聚合操作,使得一个表中的行可以通过指定的列的唯一值转换成多个列,从而使数据的查看和分析更加直观。UNPIVOT则执行与PIVOT相反的操作,将列数据转换回行。 立方体操作...
例如,在一个循环更新操作中,可以检查`@@ROWCOUNT`来确定已处理了多少行。 5. **查询时间**: 查询时间相关的SQL语句,可能涉及到`DATEDIFF()`、`GETDATE()`和`BETWEEN`等函数。`DATEDIFF()`用来计算两个日期之间...
本资源"经典SQL语句大全"涵盖了基础到高级的多种SQL知识点,旨在帮助开发者和数据爱好者提升SQL技能,提高工作效率。 1. **SQL基础** - **数据查询**: 包括`SELECT`语句,用于从表中检索数据。基本形式如:`SELECT...
下面将对这一知识点进行详细的解析。 ### SQL 行转列详解 #### 一、什么是行转列? 在数据库操作中,“行转列”(Pivot)是一种常见的数据变换需求。它指的是将原始数据表中的某些字段从行的形式转换为列的形式,...
SSAS(SQL Server Analysis Services)是微软提供的一个用于企业级数据仓库和商务智能的分析平台。它在处理大量数据和提供高效查询性能方面表现出色,同时也具有强大的扩展性,能够适应不断增长的数据需求。本篇文章...
例如,一个EAV表可能包含记录ID、元素(属性名)和值,用于存储如人名、城市等信息。查询这样的表时,需要将行数据转换为列,以便更直观地表示数据。 在不使用PIVOT运算符的情况下,可以手动实现这个转换。这通常...
假设有一个销售数据表,包含产品ID、销售日期和销售额,可以通过PIVOT操作符将按月份汇总的销售额转换成列的形式: ```sql SELECT * FROM sales PIVOT (SUM(sales) FOR EXTRACT(MONTH FROM sale_date) IN (1 AS 'Jan...
这可以是简单的SELECT语句,或者更复杂的一系列JOIN和聚合函数,用于预处理数据。 ```php $sql = "SELECT column1, column2, SUM(column3) AS total FROM table GROUP BY column1, column2"; $result = $conn->...
首先,"SQL参考手册.chm"可能是一个关于SQL语法和函数的综合指南,它通常包含以下内容: 1. **SQL基本概念**:介绍SQL的起源、用途以及关系数据库模型。 2. **数据操作语言(DML)**:包括INSERT、UPDATE、DELETE...
这些数据用于计算枢轴点(PIVOT),枢轴点是技术分析中的一个重要概念,它代表了一个市场可能反转的位置,即支撑或阻力位。 PIVOT 的计算方法是取最高价、最低价和收盘价的平均值,然后用 LINETHICK2 标记出来。R1 ...
在Laravel框架中,Compoships是一个非常有用的扩展,它扩展了Laravel的Eloquent ORM,使其能够处理复合键(也称为多键)的关系。在默认情况下,Laravel的Eloquent仅支持单一主键的关系,但许多实际数据库设计中,...
这里,我们先创建了一个名为PivotData的CTE(公共表表达式),然后使用PIVOT将`Value1`和`Value2`转换为列。PIVOT内的MAX函数用于聚合每个ID下的值,IN关键字后的括号内定义了要转成列的值列表。 这两种方法各有优...
3. 交叉表查询是为了解决一对多关系中,对"多方"实现分组求和的问题 - 交叉表查询(也称为Pivot查询)用于将行数据转换为列数据,通常用于分析和汇总数据,特别是在处理一对多关系时。 4. 查询各类商品的数量,正确...
2. ORA-00904标识符无效:这是Oracle数据库中的一个常见错误,当SQL语句中使用了无效的标识符时,会引发此错误。解决这个问题通常需要检查SQL语句中的对象名(如表名、列名)是否拼写正确,以及是否在正确的模式...
这里创建了一个名为`tb`的表,并插入了两组学生的成绩数据。 2. **实现静态SQL:** ```sql SELECT 姓名 AS 姓名, MAX(CASE 课程 WHEN '语文' THEN 分数 ELSE 0 END) 语文, MAX(CASE 课程 WHEN '数学' THEN ...
`:声明一个用于存储动态SQL语句的变量。 - `DECLARE done INT DEFAULT 0;`:声明一个控制循环的标志变量。 - `DECLARE StrSum Varchar(3000);`:声明一个用于存储求和表达式的变量。 - `DECLARE pCols Varchar...
总的来说,C#动态交叉表查询是一个结合了数据处理、数据库操作和UI展示的综合性问题,理解和掌握这些知识点对于提升数据处理能力非常有帮助。无论是在报表开发、数据分析还是BI应用中,熟练运用动态交叉表都能让你的...