Teradata SQL 编写规范

Teradata 
SQL 编写规范
目 录
1 前言...........................................................................................................................................1
1.1 边界定义........................................................................................................................................ 1
1.2 原则定义........................................................................................................................................ 1
2 格式编排约定...........................................................................................................................2
2.1 基本要求........................................................................................................................................ 2
2.2 编写规范........................................................................................................................................ 2
2.2.1 字段排列要求....................................................................................................................... 2
2.2.2 字段分割符’,’点书写位置要求 ........................................................................................... 2
2.2.3 字段别名 ‘AS’ 语句编写要求 ........................................................................................... 2
2.2.4 SELECT 子句排列要求....................................................................................................... 3
2.2.5 运算符前后间隔要求........................................................................................................... 3
2.2.6 CASE 语句的编写 ............................................................................................................... 3
2.2.7 子查询嵌套编写规范........................................................................................................... 4
2.2.8 表别名定义约定................................................................................................................... 5
3 语法及数据操作约定...............................................................................................................5
3.1 JOIN 操作语法要求 ..................................................................................................................... 5
3.2 INSERT 语句编写规范................................................................................................................ 6
3.3 DELETE 语句编写规范............................................................................................................... 7
3.4 NULL 值处理约定........................................................................................................................ 7
3.4.1 数字型字段 NULL 值的处理 .............................................................................................. 7
3.4.2 字符型字段 NULL 值的处理 .............................................................................................. 7
3.4.3 提取日期型字段的处理....................................................................................................... 7
3.5 除法运算被 0 除的处理................................................................................................................ 7
3.6 比较逻辑运算处理约定................................................................................................................ 8
3.6.1 字符型比较的处理............................................................................................................... 8
3.6.2 日期型比较的处理............................................................................................................... 8
3.7 注释约定........................................................................................................................................ 8
4 小技巧.......................................................................................................................................9
4.1 历史表的数据访问........................................................................................................................ 9
4.2 横转竖表开发.............................................................................................................................. 10
 
 SQL 编写规范
 1
1 前言
为了统一软件开发过程中关于 SQL(Structured Query Language)编码的格
式,使编码人员编写 SQL 代码遵从特定的风格,并养成良好的开发习惯,从而增
强代码的可读性,便于交流和维护,特此收集、整理公司已经积累的技术资料,
修订和编制了本编码规范。 
本规范适用于已掌握 Teradata 数据仓库系统的基本知识及 Teradata SQL 编
程技能者阅读,对从事 Teradata 数据仓库系统的代码开发、测试、检查人员起
指导的作用,也即对从事 Teradata 数据仓库系统技术工作人员必不可少的阅读
材料。 
1.1 边界定义
数据仓库系统的开发更多的是对数据进行加载、整理、抽取的工作,在项目
实施过程中经常要用到对数据进行各种形式操作的开发工作,因此对数据操作的
代码编写进行规范化的约定显的优为重要。
本规范主要用于 NCR Teradata 数据仓库系统的结构化查询语言代码编写的
标准化要求,结合 Teradata 的特点以及代码开发人员在日常编写 SQL 的
DML(Data Manipulation Language)经验,为规范 Teradata 数据仓库系统的 SQL
的 DML 开发建立统一的标准。
规范主要应用于 Teradata SQL 的 DML 以下几个语句编写约定
Select 语句;
Insert 语句;
Delete 语句;
逻辑判断语句;
类型转换语句;
以及相关的 Teradata 函数、
Teradata 数据仓库项目实施过程中数据表现形态约定等内容
在数据仓库系统项目开发中不建议使用UPDATE语句来进行数据的更新
操作,可以采用替代的中间过度表完成表中数据的重新组织,从而实现原表
数据值的更新。
1.2 原则定义
1、要求代码行清晰、整齐,具有一定的可观赏性;
2、代码编写要充分考虑执行速度最优的原则;
3、代码行整体层次分明、结构化强;
4、代码中应有必要的注释以增强代码的可读性;
5、规范要求非强制性约束代码开发人员的代码编写行为,在实际应用中在
不违反常规要求的前提下允许存在可理解的偏差。

本规范在对日常的代码开发工作起到指导作用的同时也将得到不断
 
 SQL 编写规范
 2
的完善和补充。
2 格式编排约定
2.1 基本要求
• 代码段中应用到的所有 Teradata 关键字、保留字都应大写 如
SELECT 、FROM、WHERE、AND、OR、UNION、INSERT、DELETE、
GROUP、HAVING、COUNT 等;代码行中的关键字不允许使用简写
的方式(如:SEL、DEL);Teradata V2R5 的所有保留字见附件Ⅰ;
• 表名、字段名、字段别名以首字大写加下划线连接符来命名,建议使
用规范命名(更完整的命名规则不在本规范中阐述),
• 四个空格为一个缩进量,所有的缩进皆为一个缩进量的整数位。
• 对应的括号通常要求在同一列的位置上;
• 每行宽度不超过 112200 字符(每个字符为 8 个点阵宽),超过行宽的代码
可折行与上行左对齐编排;
2.2 编写规范
2.2.1 字段排列要求
示例 1:
• SELECT 语句选择的字段按每行一个字段方式编排;
• SELECT 单字后面一个缩进量后直接跟首个选择的字段,即字段离首
起二个缩进量;
• 其它字段前导二个缩进量再跟一’’,,’’点后放置字段名;
2.2.2 字段分割符’,’点书写位置要求
• 两个字段之间的’,’点分割符紧跟在第二个字段的前面
2.2.3 字段别名 ‘AS’ 语句编写要求
• ‘AS’语句应与相应的字段在同一行;
• 多个字段的’AS’建议尽量对齐在同一列上;
示例 2:
 
 SQL 编写规范
 3

字段别名在同一个查询例程中可以被引用
2.2.4 SELECT 子句排列要求
示例 3:
SELECT 语句中所用到的
FROM、WHERE、GROUP BY、HAVING、ORDER BY、JOIN、UNION 等
子句:
• 换行编写;
• 与相应的 SELECT 语句对齐;
• 子句后续的代码离子句首字母二个缩进量起编写;
• WHERE 子句下的逻辑判断符 AND 、OR 等与 WHERE 右对齐编排
• 超过两个缩进量长度的子句加一空格后编写后续代码,如:ORDER 
BY、GROUP BY 等;
2.2.5 运算符前后间隔要求
示例 4:
算术运算符、逻辑运算符的前后至少要保留一个空格
2.2.6 CASE 语句的编写
示例 5:
 
 SQL 编写规范
 4
SELECT 语句中对字段值进行判断取值的操作将用到的 CASE 语句,正
确的编排 CASE 语句的写法对加强代码行的可阅读性也是很关键的一部
分。
我们对 CASE 语句编排作如下约定:
• CASE 语句从 CASE 开头到 END 结束要用括弧包括起来,并给结果
值赋别名字段;
• WHEN 子语在 CASE 语句的下一行并缩进两个缩进量后编写;
• 每个 WHEN 子语一行编写,当然如果语句较长可换行编排;
• CASE 语句必须包含 ELSE 子语;
2.2.7 子查询嵌套编写规范
用好子查询是提高代码执行速度的一个好方法,采用子查询来缩小结果集之
间的操作将使系统运算的开销更小,当然 Teradata 的优化器也会优化代码的处理
过程以最优的路径来完成用户的需求,但我们在编写代码时也要考虑性能的优
化。子查询嵌套在 Teradata 数据仓库系统开发中是经常要用到的,因此代码的分
层编排就非常重要。
示例 6:
 
 SQL 编写规范
 5
2.2.8 表别名定义约定
因为一旦在 SELECT 语句中给操作表定义了别名,那么在整个语句中对
此表的引用都必须惯以别名替代,因此我们考虑到编写代码的方便性,我们
约定别名尽量简单、简洁,表别名可以用 a、b、c、a1、a2、sale、buy 等来
定义,当然要避免使用 Teradata V2R5 中的保留字如:order、locator 等。
z
表别名采用简单字符命名;
z
多层次的嵌套子查询别名之前要体现层次关系;
z
有需要的情况下对表别名加注释;
示例 7:
3 语法及数据操作约定
3.1 JOIN 操作语法要求
示例 8:
 
 SQL 编写规范
 6
多个表 JOIN 取值在非 INNER JOIN 的情况下大多会取到空值,对这些
空值在程序代码中需要进行处理,同时 JOIN 操作也要注意被 JOIN 表的关键
字段值是否唯一,因此对 JOIN 语句作如下约定:
• 对有可能匹配不上而产生的空值要进行转换处理(各种类型数据的空
值转换见下文描述)
• 在此不采纳使用 RIGHT JOIN 进行表的 JOIN 操作,因为 RIGHT JOIN
完全可以用 LEFT JOIN 来实现,同时 RIGHT JOIN 在代码的逻辑上看
起来不太容易理解;
3.2 INSERT 语句编写规范
INSERT 语句在异构表之前的数据拷贝一定要带字段进行值的插入,如下所示:
示例 9:
 
 SQL 编写规范
 7
3.3 DELETE 语句编写规范
DELETE 语句将会删除数据表的信息,所以对进行 DELETE 的操作要格
外小心,一定要检查 DELETE 限定条件是否正确。
通常我们在代码开发过程中对数据进行删除操作后再进行数据的插入操
作,对这种类型的操作我们在编写代码时是将两个例程作为一个事务提交以
保证整个事务的完整性。
示例 10:
3.4 NULL 值处理约定
我们约定在提取数据的结束集中不允许存在 NULL 的值,因此对有可能
出现 NULL 值的各种类型字段需要进行特殊的值转换处理。
3.4.1 数字型字段 NULL 值的处理
说明:通过以上函数处理后,如果字段值为 NULL 将返回 0 值。
3.4.2 字符型字段 NULL 值的处理
3.4.3 提取日期型字段的处理
3.5 除法运算被 0 除的处理
为不避免在进行除法运算时被 0 除出错,我们需要对除法运算有可能出
现被 0 除的情况作特殊处理。
示例 11:
 
 SQL 编写规范
 8
说明:对有可能出现 0 的除数如果是 0 值时要把它转换为 NULL,任何
数与 NULL 相除等于 NULL,因此不会使程序出错,同时对除法运算返回值
如果是 NULL 时要把它转换为 0. 
3.6 比较逻辑运算处理约定
3.6.1 字符型比较的处理
字符型数据比较要注意大小写敏感问题;
对于字符大小写敏感字段或业务约定大小写敏感的可如下进行字符型数
值的比较
示例 12:
对于字符大小写不敏感字段或业务约定大小写不敏感的可如下进行字符
型数值的比较
3.6.2 日期型比较的处理
日期型数据比较要注意格式问题,因此我们在数据比较代码中对日期型
比较要先格式化后再比较
示例 13:
3.7 注释约定
对于较为复杂的数据操作例程应有充分的注释,注明实现的功能,业务逻辑关系输入输
出关系等内容
多行注释可用 ’ /* */’ 来标识
单行注释可用 ‘-- 来标识
示例 14:
 
 SQL 编写规范
 9
z
对于较为复杂的过程必须注明代码实现的功能以及相关的创建、修改记录;
z
在主体上有分割的代码行建议加一空白行以示区分;
4 小技巧
4.1 历史表的数据访问
/*提取某日数据*/ 
SELECT * FROM PD_DATA. ACT_ACCT_HOLD_HIS 
WHERE start_dt <=‘某日日期’ 
AND end_dt > ‘某日日期’ 
/*提取某日之前的所有数据*/ 
SELECT * FROM PD_DATA. ACT_ACCT_HOLD_HIS 
WHERE start_dt <=‘某日日期’ 
/*提取某日之后的所有数据*/ 
SELECT * FROM PD_DATA. ACT_ACCT_HOLD_HIS 
WHERE end_dt > ‘某日日期’ 
/*提取甲日和乙日之间的所有数据*/(甲日<乙日) 
SELECT * FROM PD_DATA. ACT_ACCT_HOLD_HIS 
WHERE start_dt <=‘乙日日期’ 
 
 SQL 编写规范
 10
AND end_dt > ‘甲日日期’ 
4.2 横转竖表开发
对于系统中的部分特殊的统计表进行横转竖表的开发: 
1. 这些表的字段特别多,几十甚至几百个
2. 一般表中有 1 或者 2 个 PI 字段(固定字段,即非统计字段),其余都是地位相当的
统计字段
3. 做这些表加载时采用横转竖表方式,将各统计字段进行编码,用控制表
CTL_ETL_STAT 控制
4. 建立的竖表则不像源表拥有几十几百个字段,而只拥有 1 到 2 个固定字段和一个统
计编码,统计值字段
5. 横表转竖表后,每条记录的长度都将缩短,代价是每个表的记录数都变 N 倍,假设
源表记录数为 M,其中统计字段数为 N 个,则竖表的记录数为 M*N 
EXAMPLE: 

表: 
REPORT_ID TRADE_DATE STAT01 STAT02 STAT03 STAT04 … STAT100
 1 20040803 XX XXX XXXX XXXXX QQ 
 2 20040803 XX1 XXX1 XXX1 XXXX1 QQ1 




表: 
REPORT_ID TRADE_DATE STAT_ID STAT_VALUE
 1 20040803 STAT01 XX 
 1 20040803 STAT02 XXX 
 1 20040803 STAT03 XXXX 
 1 20040803 STAT100 QQ 
 … 
 2 20040803 STAT01 XX1 
 2 20040803 STAT02 XXX1 
 … 
4.3 窗口函数与聚合函数比较
 Teradata 的窗口函数比常规聚合函数要慢很多,所以今后的 SQL 中要尽可能的向外层推
窗口函数,因为越向外,结果集越小,窗口函数的代价就会降低
4.4 关于 NOT IN 的使用
在 NOT IN 表达式中,如果 NOT IN 的子查询记录的重复系数比较高,适于在子查询中
加上 GROUP BY,显式过滤掉重复记录。
4.5 关于统计信息的收集
1 统计信息要收集就就尽量收集全面,包括所有可能用在条件中的字段以及连接用的组
合字段;
2 统计信息可以灌,只要保证上次的统计信息是好的情况下。尽量避免部分统计信息在
不同时间段重灌,一旦需要重灌,建议先将所有现有信息全 DROP 掉,在一个全初始的情
 
 SQL 编写规范
 11
况下灌入。
3 统计信息可以手工改写,但改写时要格外谨慎,避免造成与实际情况差距太大。灌入
改写后的信息后,最好对以前查询的 SQL 进行一下 EXPLAIN,以确保不会对其他查询造成
影响。
4 尽管说完全没有统计信息时,查询计划也不会很坏,但要注意统计信息对 INDEX 的
影响,因为有些 INDEX 在没有统计信息时是不起作用的。如果只灌入 INDEX 字段的统计
信息,需格外小心,用 EXPLAIN 结果证明不会出现对其他查询执行路径的影响。
5 看起来对 INDEX 字段的信息收集与对表相应字段的信息收集是一样的,只对表收集
或只对 INDEX 收集即可,无需重复进行。
4.6 关于导出表的使用
如果一个 SQL 中有两个一模一样的导出表出现在不同的地方,TERADATA 比较聪明,
只做一次,重复使用 SPOOL 中的结果,而就我在 DB2 7.0 上 EXPLAIN 的结果来看,DB2
则是要做两次。使用 WITH … AS … 这种公共表表达式时,如果此公共表被引用两次,与
上面的结果是一样的,对 TERADATA 有利。但如果不是导出表,而是 IN 或 NOT IN 中的
表达式重复使用,TERADATA 与 DB2 一样,都要执行两次。
4.7 如何从源系统历史表初始化加载 Teradata 的拉链历史表
举例说明如下:银行核心系统有传票历史文件(acpls),此数据档记录了从某一起始时点的所有
帐户的传票变动情况,每天每个账号多笔记录,关键字段如下:zhangh(账号)、jioyrq 交易日
期、huobdh 货币代号、zhhuye 帐户余额。现在的问题是要把这个“历史表”作为初始数据
加载到 Teradata 形式(带 start_dt,end_dt)的历史表中。可以参考的方法如下:
首先创建一个可变临时表用以存放上述关键字段,过滤条件是取每个帐号一天中交易时间戳
最大的那个,即每天最后一笔传票记录。
CREATE VOLATITE MULTISET TABLE WT_I AS 
 ( 
 SELECT 
 a.zhangh 
 ,a.jioyrq 
 ,a.huobdh 
 ,a.zhhuye 
 FROM 
 dwsdata.ec_acpls_060218 a 
 QUALIFY RANK() 
 OVER (PARTITION BY a.jioyrq ,a.zhangh ORDER BY a.shjnch DESC) =1 
) WITH DATA 

--再使用两条 sql 语句拉链出历史表
INSERT INTO DWPDATA.T03_AGMT_AMT_H 
 ( 
 Agmt_Num 
 ,Agmt_Modifier_Num 
 ,Amt_Type_Cd 
 ,Currency_Cd 
 ,Agmt_Bal 
 ,Start_Dt 
 ,End_Dt 
 ) 
SELECT 
 a.zhangh 
 ,'' 
 
 SQL 编写规范
 12
 ,'01' 
 ,a.huobdh 
 ,a.zhhuye 
 ,a.jioyrq 
 ,b.jioyrq 
FROM 
 wt_i a 
INNER JOIN 
 wt_i b 
ON a.zhangh=b.zhangh 
AND a.huobdh=b.huobdh 
AND a.jioyrq<b.jioyrq 
QUALIFY RANK() 
 OVER (PARTITION BY a.zhangh,a.huobdh,a.jioyrq ORDER BY b.jioyrq ) =1 
--插入一直没有变化的记录
;INSERT INTO DWPDATA.T03_AGMT_AMT_H 
 ( 
 Agmt_Num 
 ,Agmt_Modifier_Num 
 ,Amt_Type_Cd 
 ,Currency_Cd 
 ,Agmt_Bal 
 ,Start_Dt 
 ,End_Dt 
 ) 
SELECT 
 a.zhangh 
 ,'' 
 ,'01' 
 ,a.huobdh 
 ,a.zhhuye 
 ,a.jioyrq 
 ,'30001231' 
FROM 
 wt_i a 
QUALIFY RANK() 
 OVER (PARTITION BY a.zhangh,a.huobdh ORDER BY a.jioyrq DESC) =1 

至此,传票历史表已经初始加载到数据仓库的历史表中了。当然,一般都有初始数据下载,
所以在产生可变临时表时需要增加过滤条件 jioyrq>’起始日期’,之后再下载起始日期的时
点数据先加载到历史表中。
4.8 排序函数
在开发过程中经常会使用到一些排序操作,下面就 ANSI 和 Teradata 的处理方式分别介
绍。
我们的表结构如下:
SELECT * FROM salestbl ORDER BY 1,2; 
 storeid prodid sales 
 ----------- --------- ------------- 
 1001 A 100000.00 
 1001 C 60000.00 
 
 SQL 编写规范
 13
 1001 D 35000.00 
 1001 F 150000.00 
 1002 A 40000.00 
 1002 C 35000.00 
 1002 D 25000.00 
 1003 A 30000.00 
 1003 B 65000.00 
 1003 C 20000.00 
 1003 D 50000.00 
找到卖得最好的三种产品:
Teradata 语法:
SELECT storeid, prodid, sales, RANK(sales) AS Rank_Sales 
FROM salestbl QUALIFY Rank_Sales <= 3 

storeid prodid sales Rank_Sales
------- ------- --------- ----------
1001 F 150000.00 1
1001 A 100000.00 2
1003 B 65000.00 3
值得注意的是,在 Teradata 的 rank 中,是默认为降序排列的。
为了达到相同目的,ANSI 是这样做的:
SELECT storeid, prodid, sales, RANK() OVER (ORDER BY sales DESC) AS 
Rank_Sales 
FROM salestbl 
QUALIFY rank_sales <= 3; 
storeid prodid sales Rank_Sales
------- ------- --------- ----------
1001 F 150000.00 1
1001 A 100000.00 2
1003 B 65000.00 3
值得注意的是,在 ANSI 的 order by 中,默认为升序排列的。
下面在让我们研究一下分组排序。
找到每个商店卖的最好的三种产品:
Teradata:
SELECT storeid, prodid, sales, RANK(sales)AS Rank_Sales 
FROM salestbl 
GROUP BY storeid 
QUALIFY Rank_Sales <= 3 

storeid prodid sales Rank_Sales
------- ------- --------- ---------
1001 F 150000.00 1
1001 A 100000.00 2
1001 C 60000.00 3
1002 A 40000.00 1
 
 SQL 编写规范
 14
1002 C 35000.00 2
1002 D 25000.00 3
1003 B 65000.00 1
1003 D 50000.00 2
1003 A 30000.00 3
ANSI:
SELECT storeid, prodid, sales, RANK() 
 OVER (PARTITION BY storeid ORDER BY sales DESC)AS rank_sales
FROM salestbl
QUALIFY rank_sales <= 3;
这里 partition by 扮演了 group by 的角色。
一些 Teradata Rank 例子:
SELECT t.prodid, t.sumsales, rank(t.sumsales) 
FROM (SELECT a.prodid, SUM(a.sales) FROM salestbl a 
 GROUP BY 1) AS t(prodid, sumsales) 
QUALIFY RANK(sumsales ASC) <= 3; 
也可以使用 ROW_NUMBER 函数,跟 rank 一样,除了相等处理之外
Example 1 
Rank product sales within a store using the RANK function. 
SELECT storeid, prodid, sales, 
RANK() OVER 
(PARTITION BY storeid ORDER BY sales DESC) AS rank_sales FROM salestbl 
QUALIFY rank_sales <= 3;
 storeid prodid sales rank_sales 
----------- ------ ----------- ----------- 
 1001 F 150000.00 1 
 1001 A 100000.00 2 
 1001 C 60000.00 3 
 1002 A 40000.00 1 
 1002 C 35000.00 2 
 1002 D 25000.00 3 
 1003 B 65000.00 1 
 1003 D 50000.00 2 
 1003 A 30000.00 3 
Example 2 
Rank product sales within a store using the ROW_NUMBER function. 
SELECT storeid, prodid, sales, 
ROW_NUMBER() OVER 
(PARTITION BY storeid ORDER BY sales DESC)AS rank_sales FROM salestbl 
QUALIFY rank_sales <= 3;
 
 SQL 编写规范
 15
 storeid prodid sales rank_sales 
----------- ------ ----------- ----------- 
 1001 F 150000.00 1 
 1001 A 100000.00 2 
 1001 C 60000.00 3 
 1002 A 40000.00 1 
 1002 C 35000.00 2 
 1002 D 25000.00 3 
 1003 B 65000.00 1 
 1003 D 50000.00 2 
 1003 A 30000.00 3 
 
Example 3 
Rank sales of item 10 by day between the two specified dates using the 
RANK function. 
SELECT itemid, salesdate, sales, 
RANK() OVER (ORDER BY sales DESC) 
WHERE salesdate BETWEEN 980101 and 980301 
FROM daily_sales ;
 itemid salesdate sales Rank(sales) 
----------- ---------- ----------- ----------- 
 10 1998-01-10 550.00 1 
 10 1998-02-17 550.00 1 
 10 1998-02-20 450.00 3 
 10 1998-02-06 350.00 4 
 10 1998-02-27 350.00 4 
 10 1998-01-05 350.00 4 
 10 1998-01-03 250.00 7 
 10 1998-02-03 250.00 7 
 10 1998-01-25 200.00 9 
 10 1998-01-02 200.00 9 
 10 1998-01-21 150.00 11 
 10 1998-02-01 150.00 11 
 10 1998-01-01 150.00 11 
 10 1998-01-31 100.00 14 
注意相同的 rank number 
Example 4 
Rank sales of item 10 by day between the two dates specified using 
ROW_NUMBER. 
 
 SQL 编写规范
 16
SELECT itemid, salesdate, sales, 
ROW_NUMBER() OVER (ORDER BY sales DESC) 
WHERE salesdate BETWEEN 980101 and 980301 
AND itemid = 10 
FROM daily_sales;
 itemid salesdate sales Row_Number() 
----------- ---------- ----------- ------------ 
 10 1998-01-10 550.00 1 
 10 1998-02-17 550.00 2 
 10 1998-02-20 450.00 3 
 10 1998-02-06 350.00 4 
 10 1998-02-27 350.00 5 
 10 1998-01-05 350.00 6 
 10 1998-01-03 250.00 7 
 10 1998-02-03 250.00 8 
 10 1998-01-25 200.00 9 
 10 1998-01-02 200.00 10 
 10 1998-01-21 150.00 11 
 10 1998-02-01 150.00 12 
 10 1998-01-01 150.00 13 
 10 1998-01-31 100.00 14 
注意相同金额不同排名 
在实际使用时候,可以根据你的使用偏好,选择一种写法,在 Teradata 中执行效率无差别。
4.9 其他函数
4.9.1 sum 
SELECT storeid, prodid, sales, 
SUM(sales) OVER (ORDER BY sales DESC) 
FROM salestbl;
 storeid prodid sales Group Sum(sales) 
----------- ------ ----------- ---------------- 
 1001 F 150000.00 610000.00 
 1001 A 100000.00 610000.00 
 1003 B 65000.00 610000.00 
 1001 C 60000.00 610000.00 
 1003 D 50000.00 610000.00 
 1002 A 40000.00 610000.00 
 1001 D 35000.00 610000.00 
 1002 C 35000.00 610000.00 
 1003 A 30000.00 610000.00 
 
 SQL 编写规范
 17
 1002 D 25000.00 610000.00 
 1003 C 20000.00 610000.00 
SELECT storeid, prodid, sales, 
SUM(sales) OVER (PARTITION BY prodid ORDER BY sales DESC) 
FROM salestbl ;
 storeid prodid sales Group Sum(sales) 
----------- ------ ----------- ---------------- 
 1001 A 100000.00 170000.00 
 1002 A 40000.00 170000.00 
 1003 A 30000.00 170000.00 
 1003 B 65000.00 65000.00 
 1001 C 60000.00 115000.00 
 1002 C 35000.00 115000.00 
 1003 C 20000.00 115000.00 
 1003 D 50000.00 110000.00 
 1001 D 35000.00 110000.00 
 1002 D 25000.00 110000.00 
 1001 F 150000.00 150000.00 
Note that the Group Sum reflects the total for each product. 
Show the totals for each store across all products. 
SELECT storeid, prodid, sales, 
SUM(sales) OVER (PARTITION BY storeid ORDER BY sales DESC 
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) 
FROM salestbl;
 storeid prodid sales Group Sum(sales) 
----------- ------ ----------- ---------------- 
 1001 F 150000.00 345000.00 
 1001 A 100000.00 345000.00 
 1001 C 60000.00 345000.00 
 1001 D 35000.00 345000.00 
 1002 A 40000.00 100000.00 
 1002 C 35000.00 100000.00 
 1002 D 25000.00 100000.00 
 1003 B 65000.00 165000.00 
 1003 D 50000.00 165000.00 
 1003 A 30000.00 165000.00 
 1003 C 20000.00 165000.00 
Things to notice: 
The Group Sum reflects the total for each store. 
 
 SQL 编写规范
 18
The key words ROWS BETWEEN UNBOUNDED PRECEDING AND 
UNBOUNDED FOLLOWING are unnecessary since they are the default.. 
The same result could have been produced with the following query: 
SELECT storeid, prodid, sales, 
SUM(sales) OVER 
(PARTITION BY storeid ORDER BY sales DESC) 
FROM salestbl;
4.9.2 Min,Max 
SELECT storeid, prodid, sales, 
MIN(sales) OVER 
(PARTITION BY storeid ORDER BY sales DESC) 
FROM salestbl;
 storeid prodid sales Group Min(sales) 
----------- ------ ----------- ---------------- 
 1001 F 150000.00 35000.00 
 1001 A 100000.00 35000.00 
 1001 C 60000.00 35000.00 
 1001 D 35000.00 35000.00 
 1002 A 40000.00 25000.00 
 1002 C 35000.00 25000.00 
 1002 D 25000.00 25000.00 
 1003 B 65000.00 20000.00 
 1003 D 50000.00 20000.00 
 1003 A 30000.00 20000.00 
 1003 C 20000.00 20000.00 
Use of the MAXIMUM function with Group Window 
The MAXIMUM Window function reports the maximum value for the defined 
group. 
Show the sales figure for the best performing product in each store. 
SELECT storeid, prodid, sales, 
MAX(sales) OVER 
(PARTITION BY storeid ORDER BY sales DESC) 
FROM salestbl;
 storeid prodid sales Group Max(sales) 
----------- ------ ----------- ---------------- 
 1001 F 150000.00 150000.00 
 1001 A 100000.00 150000.00 
 1001 C 60000.00 150000.00 
 
 SQL 编写规范
 
 1001 D 35000.00 150000.00 
 1002 A 40000.00 40000.00 
 1002 C 35000.00 40000.00 
 1002 D 25000.00 40000.00 
 1003 B 65000.00 65000.00 
 1003 D 50000.00 65000.00 
 1003 A 30000.00 65000.00 
 1003 C 20000.00 65000.00 

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一鸣888

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值