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. 【poj3141】 Distant Galaxy

    http://poj.org/problem?id=3141 (题目链接) 题意 给出平面上n个点,找出一个矩形,使边界上包含尽量多的点. solution 不难发现,除非所有输入点都在同一行或同一列 ...

  2. javascript向上向下取整

    alert(Math.ceil(25.9)); alert(Math.ceil(25.5)); alert(Math.ceil(25.1)); alert(Math.round(25.9)); ale ...

  3. Linux内核版本类型

    对于Linux内核发布的版本类型有如下,也是自己的理解: [mainline]:主线版本,由Linux Torvalds维护和发布. [stable/EOL]:稳定版本,每个由主线发布的版本都叫做稳定 ...

  4. [资料搜集狂]D3.js数据可视化开发库

    偶然看到一个强大的D3.js,存档之. D3.js 是近年来十分流行的一个数据可视化开发库. 采用BSD协议 源码:https://github.com/mbostock/d3 官网:http://d ...

  5. CentOS关闭火狐浏览器Flash过期提示

    关闭旧版插件屏蔽提示 打开 about:config?filter=extensions.blocklist.enabled 右键切换,关闭flash版本过旧被屏蔽的提示. 参考: http://ti ...

  6. 使用enum建立简单的状态机

    Overview The enum in Java is more powerful than many other languages which can lead to surprising us ...

  7. C#12种顺序排序

    这篇主要写关于顺序排序的十二种算法,也是我有关算法的第一帖.主要是写,对每种算法的理解与测试. 速度测试,主要根据一千.一万.五万.百万这 四种.速度纪录还是用Stopwatch 这个类.使用随机数R ...

  8. Always review

    Data structures A data structure is a way to store and organize data in order to facilitate access a ...

  9. HTML5学习总结-05 HTML5表单

    一 HTML5 新的类型 HTML5 拥有多个新的表单输入类型.这些新特性提供了更好的输入控制和验证. email url number range Date pickers (date, month ...

  10. SQL Server 2012 学习笔记2

    1. 新建数据库 可以在对应目录下右键新建数据库,也可以用程序添加: 先打开程序编辑对话框"New Query" create database Library 2. 添加表格 可 ...