Teradata的SQL设计和Oracle真不是一个水平, 一点美感的没有.  
上个世纪它靠着MPP一招鲜吃变天, 居然做了十多年数据仓库的老大,  时过境迁, 现在有不少SQL On Hadoop 产品已经出来了, 考虑到scale out的成本和能力, Teradata 数据仓库优势荡然全无. 将来必将会被SQL on Hadoop/Spark替代.

毕竟在Teradata上做了几年, 也该写点总结. 下面是我常用的一些编程知识

--字符串函数
    SELECT 'FirstName' || ' ' || 'LastName' as Full_Name;
    CHAR2HEXINT ('A')
    --would result in the value ‘0041’.
    LOWER()
    substr()
    TRIM()
    UPPER()
    CHARACTERS() 或 character_length() 得到字符串的长度
    SELECT position ('a' in 'Name')
    oracle version replace(), no way. write your code

---type() 可返回 字段的类型,
SELECT
    CAST(100.00 AS DECIMAL(15,2)) * CAST(100.00 AS DECIMAL(15,2)) AS C1
  , TYPE(C1)

--获取字段类型
select type('abc')

--get current date
select current_date
select current_time
select current_timestamp(0) --不带毫秒
select current_timestamp --带6位毫秒, 最高精度

--日期加减
select current_date+1 --得到明天
select add_months(current_timestamp,1)  --得到下一个月
select add_months(current_date ,1)-current_date --两个日期相差多少天
select add_months(current_timestamp,1) -current_timestamp day(4) to second --两个时间戳相减, 仍是时间戳

--使用INTERVAL进行时间日期的增减
Select current_date + interval '1' year
Select current_date - interval '1' year
Select current_date + interval '1' month
Select current_date + interval '1' day
Select current_timestamp + interval '1' hour
Select current_timestamp + interval '1' minute
Select current_timestamp + interval '1' second

--两个 timestamp 相减, 结果仍是一个timestamp, 而日期相减, 结果为相差的天数
select cast (endtime as   timestamp(0)  format 'yyyy-mm-ddbhh:mi:ss') -
           cast (starttime as   timestamp(0)  format 'yyyy-mm-ddbhh:mi:ss') DAY(4) TO SECOND ,
        a. *  from      PETL.ETL_JOB_STATUS A
where 1=1
and jobstatus='Done';
The DAY(4) specifies four digits of precision, and allows for a maximum of 9999 days, or
approximately 27 years.

-- timestamp 相减, 前3个写法, 要求时间跨度不能太大, 会溢出的
select ((current_timestamp + interval '1' hour )  -current_timestamp)  day(4)           --得到的差多少天
select ((current_timestamp + interval '1' hour )  -current_timestamp)  hour(4)          --得到的差多少小时
select ((current_timestamp + interval '25' hour ) -current_timestamp)  minute(4)        --得到的差多少分
select ((current_timestamp + interval '1' hour )  -current_timestamp)  day(4) to second --得到的是timestamp

--统计执行总时长
select txdate
,sum(extract(DAY from duration)) * 24.000
+sum(extract(HOUR from duration)) *1.000
+sum(extract(MINUTE from duration)) /60.000
+sum(extract(SECOND from duration)) /3600.000
   as duration_hours from
(
select  cast (endtime as   timestamp(0)  format 'yyyy-mm-ddbhh:mi:ss') -
        cast (starttime as   timestamp(0)  format 'yyyy-mm-ddbhh:mi:ss') day(4) TO SECOND  duration,
        txdate  from     PETL.ETL_JOB_STATUS A
where 1=1
and jobstatus='Done'
and A.txdate>=date'2012-06-01'
and A.txdate<date'2012-07-19'
)  xx
group by  xx.txdate
order by  xx.txdate
;

--从日期中提取年月日
select EXTRACT(YEAR  FROM  current_date)
    YEAR
    MONTH
    DAY
    HOUR
    MINUTE
    SECOND
    TIMEZONE_HOUR
    TIMEZONE_MINUTE
    
    
--几个有用的查询    
select user
select session
select role    
select * from sys_calendar.calendar

--字符转日期
select date'2012-05-12'
select CAST('20120512' AS DATE FORMAT 'YYYYMMDD')

--字符转 timestamp
select cast ('20120512 231056'  as timestamp(0) FORMAT 'YYYYMMDDBHHMISS' )

--日期 转 字符串
--recommended usage, statement 1
SELECT CAST(cast(current_date AS FORMAT 'yyyymmdd') as varchar(8))
select current_date (format 'YYYYMMDD') (varchar(8))

--timestamp 转 字符串
--recommended usage, statement 1
SELECT CAST(CAST(TIMESTAMP'2010-03-12 14:32:45' AS FORMAT 'yyyymmddbhh:mi:ssbt') AS varchar(20));
select current_timestamp (format 'YYYYMMDDBHHMISS') (varchar(15))
SELECT CAST(TIMESTAMP'2010-03-12 14:32:45' AS FORMAT 'yyyymmddbhh:mi:ssbt') (varchar(20));

--error when runing
select current_date (format 'YYYYMMDD') (varchar(8))||'abc'
--how to achieve
select CAST(cast(current_date AS FORMAT 'yyyymmdd') as varchar(8))||'abc'

--合并日期和时间 为 timestamp
SELECT CAST(CAST(CURRENT_DATE AS FORMAT 'YYYY-MM-DD') || ' ' || CAST(CAST(CURRENT_TIME AS FORMAT 'HH:MI:SS') AS CHAR(8)) AS TIMESTAMP(0));

--searched case 语句
case
    when AA=v1 then r1
    when AA=v2 then r2
    else null
end
--value case 语句
case AA
    when v1 then r1
    when v2 then r2
    else null
end

--case 变种 NULLIF
NULLIF returns NULL if its arguments are equal. Otherwise, it returns its first argument,
scalar_expression_1.
--case 变种 COALESCE
COALESCE returns NULL if all its arguments evaluate to null. Otherwise, it returns the value
of the first non-null argument in the scalar_expression list.
oracle:nvl(f1,f2...),teradata:coalesce(f1,f2...)

=====================================
 建表  
=====================================
--创建 MULTISET 表
 MULTISET:默认为 SET;
 NO LOG:默认为 LOG,LOG指示维护交易日志,NO LOG 的性能更好;
 
create MULTISET table t1
(f1 integer, f2 integer) PRIMARY INDEX ( f1 )  ;
;
 
--创建临时表  
CREATE MULTISET TABLE PDATA.EQP_PERF_HIS_SS1_CUR_I AS PDATA.EQP_PERF_HIS
WITH NO DATA
PRIMARY index (fab_code)
;
 CREATE MULTISET TABLE PDATA.EQP_PERF_HIS_SS1_CUR_I AS (select * from PDATA.EQP_PERF_HIS)
 WITH NO DATA
 --WITH DATA
 PRIMARY index (fab_code)
 ;
 真正的临时表 volatile , session 结束后自动drop, 也可以手动删除
 CREATE VOLATILE MULTISET TABLE PDATA.EQP_PERF_HIS_SS1_CUR_I AS (select * from PDATA.EQP_PERF_HIS)
 WITH NO DATA
 --WITH DATA
 PRIMARY index (fab_code)
 
 还有一种 GLOBAL TEMPORARY  TABLE, 不常用.
 
 
 
大小写敏感
--default, 大小写不敏感
select f from (select 'a' f ) dual_a  where 1=1 and f = 'A'
select f from (select 'a' f ) dual_a  where 1=1 and f like '%A%'
--大小写敏感的写法
select f from (select 'a' f ) dual_a  where 1=1 and f(casespecific) like '%A%'

select * from scott.emp where ename(CASESPECIFIC) = 'FAN';--使用关键字CASESPECIFIC将区分大小写
 
    
转义 _ 字符, 下例是使用\取转义_
select * from like_escape_test where some_text like '%\_%' escape '\';
    
top n 语句
  select top 10 * from table_a order by field_a;

UPDATE Specifying a Correlation Name for the Updated Table in the FROM Clause
需要说明的是, SET 子句中的目标字段不能加表名alias.
    UPDATE e
    FROM employee AS e, department AS d
    SET salary = salary * 1.05
    WHERE e.emp_no = d.emp_no
    AND d.name LIKE '%Support%'    
    
    
    
update join 语句
    UPDATE employee
    SET salary_amount=salary_amount * 1.10
    WHERE employee.dep_no = department.dep_no
    AND department.name LIKE '%Support%'
    ;

Note: In an update, you can't use the ON clause,
so the join condition is specified in the WHERE clause.

在SP中, 可以使用变量,  但在Macro中, 是不能使用变量. 声明变量必须放在SP的开头部分. 语法为:
DECLARE vcount INTEGER DEFAULT 0;
DECLARE temp1, par1 VARCHAR(40) DEFAULT NULL;

Teradata没有 oracle的打印功能, 下面的语句并不能输出
PRINT 'EmpNo:', vcount;

使用游标 cursor
FOR loopvar AS cur1 CURSOR FOR
SELECT employee_number, department_number FROM employee
DO
     PRINT 'EmpNo:', loopvar.employee_number;
END FOR;
上面的例子中示范了游标的规则:
1.声明游标,需要使用 FOR 语句。
2.要赋予游标一个名字,例子中的名字为 cur1
3.要给循环赋一个名字 loopvar

定义SP
REPLACE PROCEDURE PDATA.SP_WAT_PARAMETERS()
BEGIN
END;

定义Macro
REPLACE  MACRO MARTVIEW_KPI.EIS_INDEX_RESULT_MACRO(SQL_Date VARCHAR(20))
AS
(
);

-- 动态执行sql语句
--===========================
SET Sql_text = 'DELETE FROM temp_Table' ;
CALL DBC.SYSEXECSQL(:Sql_text) ;

=====================================
-- bteq 命令行工具
=====================================
bteq工具的调用方法是:
bteq <sql_file.btq >log.txt

下面是sql_file.btq文件的内容
.LOGON  ip/userid,pwd

drop table     SMCTA.SS1SDBSDB_TB_INFO_EQP4687                 ;
;
.IF ERRORCODE <> 0 THEN .GOTO QUITWITHERROR;

SELECT 1 ;

.IF ACTIVITYCOUNT = 0 THEN .GOTO QUITWITHNOERROR;
.GOTO QUITWITHNOERROR;

.LABEL QUITWITHERROR
.LOGOFF;
.QUIT 12;

.LABEL QUITWITHNOERROR
.LOGOFF;
.QUIT 0;

.LOGOFF
上面是sql_file.btq文件的内容

=====================================
-- jdbc访问
=====================================
JDBC connection string:
url="jdbc:teradata://edwprd/TMODE=TERA,CHARSET=ASCII,CLIENT_CHARSET=cp936,DATABASE=TESTDB,lob_support=off"
edwprd为IP, 考虑到Teradata是多节点一体机, 最好是在hosts中,  定义一个域名解析规则, 这样就有了多节点冗余的功能.

Hosts:
153.65.129.189                   edwprd  dbccop1
153.65.129.190                   edwprd  dbccop2
153.65.129.191                   edwprd  dbccop3
153.65.129.192                   edwprd  dbccop4

Teradata SQL programming的更多相关文章

  1. Qt SQL Programming 部分翻译

    简介:      Qt SQL 是 Qt 的重要模块之一,为了方便,Qt 对 SQL 进行了一系列的封装,并将 SQL API 分为如下三层:      (1)驱动层      (2)SQL API ...

  2. 【Teradata SQL】行转列函数TDStats.udfConcat

    TDstats.udfConcat为Teradata自带UDF,定义如下: show function tdstats.udfconcat; REPLACE FUNCTION tdstats.UDFC ...

  3. TERADATA SQL学习随笔<一>

    此博客内容简介及目录 http://www.cnblogs.com/weibaar/p/6644261.html 最近在TERADATA环境学习SQL.在这里记录一下学习中查过的知识点,作为备案. 目 ...

  4. Teradata SQL tips

    Question: Insert into table_name  (1),(2),.... Teradata 貌似不能同时插入,只能一条一条插入,报错. 后来改为: Insert into tabl ...

  5. pl/sql programming 15 数据提取

    数据提取 -- 游标 游标只是一个指向某个结果集的指针. 声明游标: cursor employee_cur IS select * from employees; 打开游标: open employ ...

  6. pl/sql programming 06 异常处理

    如果 PLSQL发生了错误, 无论是系统错误还是应用错误, 都会抛出一个异常, 当前 PL/SQL 块中执行单元会暂停处理, 如果当前块有一个异常处理单元的话, 控制会转移到当前块的异常处理单元来处理 ...

  7. pl/sql programming 03 语言基础

    PL/SQL 块结构 最小的有意义的代码单元叫做 块(block). 一个块是一组代码, 这个块给出了执行边界, 也为变量声明和异常处理提供了作用范围, pl/sql 准许我们创建匿名块和命名块, 命 ...

  8. pl/sql programming 02 创建并运行plsql代码

    /* * chap 02 * ------------------------------------------------- */ create or replace function wordc ...

  9. 【Teradata SQL】字符串分割函数STRTOK和STRTOK_SPLIT_TO_TABLE

    STRTOK函数: 按照指定分隔符,将字符串分割成多个部分,返回指定部分字符串. 参数说明: (1)instring:字符串或字符串表达式. (2)delimiter:分隔符列表,字符串每个字符都会做 ...

随机推荐

  1. Diccuz!NT的dll版本号控制技巧

    dnt每次发布新版本时,公布出来的版本号都是3位数以上,拿3.6.711这个版本号的代码来说,几乎每一个dll上都是统一的版本号命名: 对于一个成熟的产品来说,统一一致的版本号命名有以下的好处: 1. ...

  2. 洛谷P1565 牛宫

    题目描述 AP 神牛准备给自己盖一座很华丽的宫殿.于是,他看中了一块N*M 的矩形空地. 空地中每个格子都有自己的海拔高度.AP 想让他的宫殿的平均海拔在海平面之上(假设 海平面的高度是0,平均数都会 ...

  3. PHP解释器引擎执行流程 - [ PHP内核学习 ]

    catalogue . SAPI接口 . PHP CLI模式解释执行脚本流程 . PHP Zend Complile/Execute函数接口化(Hook Call架构基础) 1. SAPI接口 PHP ...

  4. linux: shell常用指令归纳

    1.软件安装方式: 1)源码安装: ~ wget xxxxxx ~ ./configure ~ make ~ make install 2) yum: ~ yum search : 查找软件包 ~ y ...

  5. 数据结构算法C语言实现(十一)--- 3.4队列的链式表示和实现

    一.简介 FIFO. 二.头文件 //3_4_part1.h /** author:zhaoyu email:zhaoyu1995.com@gmail.com date:2016-6-9 note:r ...

  6. AngularJs ngHref、ngSrc、ngCopy/ngCut/ngPaste

    ngHref 在Angular程序没完成改变链接上用{{hash}}方式绑定的href值的时候,当用户点击该链接会跳到一个错误的页面. 格式:ng-href=”value” value:表达式. 使用 ...

  7. POJ 1804 Brainman(归并排序)

    传送门 Description Background Raymond Babbitt drives his brother Charlie mad. Recently Raymond counted ...

  8. 【项目】Http请求在NSMutableURLRequest添加HttpBody的字典params属性

    在请求头中加入字典集合的Body,首先把字典转换成json,然后json转换成NSData,然后加入到HTTPBody中,我有已下写法 // 参数paramsNSDictionary * params ...

  9. Altium Designer 15 --- Design PCB Frame by Rhinoceros

    step 1: Draw a PCB shape and the main component placed in the PCB. The drawing sheet should be in th ...

  10. 一文彻底了解join的各种用法

    表a                       表b    a1    a2                 b1     b2 a01     张三         a02     数学 a02 ...