SQL常用函数

ORACLE

建表

(1)建一个新表,架构、字段属性、约束条件、数据记录跟旧表完全一样:

Create Table print_his_0013 as Select * from print_his_0007 

(2)建一个新表,架构跟旧表完全一样,但没有内容:

Create Table print_his_0013 as Select * from print_his_0007 where 1=2

 (3)建一个新表,只选部分字段:

CREATE TABLE yonghu_bak AS SELECT id, name,sex FROM yonghu;

函数row_number()

当遇到一个部门有多个员工记录,需要去取出每个部门薪水最少的那笔时,就可以用到分析函数row_number()

select * from(

        select manager_id,employee_id,first_name,salary,row_number() 

        over(partition by manager_id order by salary) as currowid

       from hr.employees)

where currowid = 1

行转列

student subject grade

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

student1 语文 80

student1 数学 70

student1 英语 60

student2 语文 90

student2 数学 80

student2 英语 100

……

转换为 

语文 数学 英语

student1 80 70 60

student2 90 80 100

……

 

语句1:

select student,sum(decode(subject,'语文', grade,null)) "语文",

sum(decode(subject,'数学', grade,null)) "数学",

sum(decode(subject,'英语', grade,null)) "英语"

from table

group by student

oracle 10g wmsys.wm_concat行列转换函数的使用 

wm_concat(列名),该函数可以把列值以","号分隔起来,并显示成一行

 http://www.linuxidc.com/Linux/2012-04/58992.htm

解锁

--查出oracle当前的被锁对象

SELECT l.session_id sid,

       s.serial#,

       l.locked_mode 锁模式,

       l.oracle_username 登录用户,

       l.os_user_name 登录机器用户名,

       s.machine 机器名,

       s.terminal 终端用户名,

       o.object_name 被锁对象名,

       s.logon_time 登录数据库时间

FROM v$locked_object l, all_objects o, v$session s

WHERE l.object_id = o.object_id

   AND l.session_id = s.sid

ORDER BY sid, s.serial#;

--kill掉当前的锁对象可以为

alter system kill session 'sid,s.serial#';

SELECT * FROM V$DB_OBJECT_CACHE WHERE  owner='FM' AND NAME LIKE '%FM_RECORD_BAK%' AND LOCKS!='0'

创建表空间

create tablespace user_data  

logging  

datafile 'D:\oracle\oradata\Oracle9i\user_data.dbf' 

size 50m  

autoextend on  

next 50m maxsize 20480m  

extent management local; 

sys_connect_by_path

select 'select '|| wm_concat('t.'||column_name) || ' from TB_INDEX t' from user_tab_columns where table_name='TB_INDEX';

sys_connect_by_path(columnname, seperator) :用来构造树路径的,所以需要和connect by一起来用。

sys_connect_by_path 函数主要作用是可以把一个父节点下的所有子节点通过某个字符进行区分,然后连接在一个列中显示 

SQL常用函数_第1张图片

select t.areaid,

       t.parentareaid,

       t.areaname,

       sys_connect_by_path(t.areaname, '-') area 

  from tb_index t

 start with t.areaname = '中国'

connect by t.parentareaid = prior t.areaid;

SQL常用函数_第2张图片

listagg

11gr2还新增了一个分析函数LISTAGG,这个函数的功能实现字符串的连接

create table t (id number, name varchar2(30), type varchar2(20));

insert into t

  select rownum, object_name, object_type from dba_objects;

select listagg(name, ',') within group(order by id)

  from t

 where rownum < 10;

select type, listagg(name, ',') within group(order by id) name

 from t

where type in ('DIRECTORY', 'JAVA SOURCE', 'SCHEDULE')

group by type;

select name,

       listagg(name, ',') within group(order by id) over(partition by type) s_name

  from t

 where type in ('DIRECTORY', 'JAVA SOURCE', 'SCHEDULE');

字符串

select instr('hgda', 'a', -1) from dual;

倒序查找

select length('123afgha56a789') -
       regexp_instr(reverse('123afgha56a789'), 'a', 1) + 1 opt
  from dual;

正则表达式

SELECT LENGTH(REGEXP_REPLACE(REPLACE('123,45,6,5'',''@'), '[^@]+''')) COUNT

  FROM DUAL;

CASE WHEN

1

CASE sex  

WHEN '1' THEN '男'  

WHEN '2' THEN '女'  

ELSE '其他' END  

--

CASE

WHEN sex = '1' THEN '男'  

WHEN sex = '2' THEN '女'  

ELSE '其他' END  

 

CASE WHEN 在语句中不同位置的用法

2.1 SELECT CASE WHEN 用法

SELECT   grade, COUNT (CASE WHEN sex = 1 THEN 1      /*sex 1为男生,2位女生*/

                       ELSE NULL

                       END) 男生数,

                COUNT (CASE WHEN sex = 2 THEN 1

                       ELSE NULL

                       END) 女生数

    FROM students GROUP BY grade;

 

2.2 WHERE CASE WHEN 用法

SELECT T2.*, T1.*

   FROM T1, T2

  WHERE (CASE WHEN T2.COMPARE_TYPE = 'A' AND

                   T1.SOME_TYPE LIKE 'NOTHING%'

                THEN 1

              WHEN T2.COMPARE_TYPE != 'A' AND

                   T1.SOME_TYPE NOT LIKE 'NOTHING%'

                THEN 1

              ELSE 0

           END) = 1

 

2.3 GROUP BY CASE WHEN 用法

SELECT  

CASE WHEN salary <= 500 THEN '1'  

WHEN salary > 500 AND salary <= 600  THEN '2'  

WHEN salary > 600 AND salary <= 800  THEN '3'  

WHEN salary > 800 AND salary <= 1000 THEN '4'  

ELSE NULL END salary_class, -- 别名命名

COUNT(*)  

FROM    Table_A  

GROUP BY  

CASE WHEN salary <= 500 THEN '1'  

WHEN salary > 500 AND salary <= 600  THEN '2'  

WHEN salary > 600 AND salary <= 800  THEN '3'  

WHEN salary > 800 AND salary <= 1000 THEN '4'  

ELSE NULL END;  

3.关于IF-THEN-ELSE的其他实现

3.1 DECODE() 函数

select decode(sex, 'M', 'Male', 'F', 'Female', 'Unknown')

from   employees;

貌似只有Oracle提供该函数,而且不支持ANSI SQL,语法上也没CASE WHEN清晰,个人不推荐使用。

 

3.2 在WHERE中特殊实现

SELECT T2.*, T1.*

   FROM T1, T2

  WHERE (T2.COMPARE_TYPE = 'A' AND T1.SOME_TYPE LIKE 'NOTHING%')

         OR

        (T2.COMPARE_TYPE != 'A' AND T1.SOME_TYPE NOT LIKE 'NOTHING%')

TRUNC

 

1.select trunc(sysdate) from dual  --2011-3-18  今天的日期为2011-3-18
2.select trunc(sysdate, 'mm')   from   dual  --2011-3-1    返回当月第一天.
3.select trunc(sysdate,'yy') from dual  --2011-1-1       返回当年第一天
4.select trunc(sysdate,'dd') from dual  --2011-3-18    返回当前年月日
5.select trunc(sysdate,'yyyy') from dual  --2011-1-1   返回当年第一天
6.select trunc(sysdate,'d') from dual  --2011-3-13 (星期天)返回当前星期的第一天
7.select trunc(sysdate, 'hh') from dual   --2011-3-18 14:00:00   当前时间为14:41  
8.select trunc(sysdate, 'mi') from dual  --2011-3-18 14:41:00   TRUNC()函数没有秒的精确
/***************数字********************/
/*
TRUNC(number,num_digits)
Number 需要截尾取整的数字。
Num_digits 用于指定取整精度的数字。Num_digits 的默认值为 0。
TRUNC()函数截取时不进行四舍五入
*/
9.select trunc(123.458) from dual --123
10.select trunc(123.458,0) from dual --123
11.select trunc(123.458,1) from dual --123.4
12.select trunc(123.458,-1) from dual --120
13.select trunc(123.458,-4) from dual --0
14.select trunc(123.458,4) from dual  --123.458
15.select trunc(123) from dual  --123
16.select trunc(123,1) from dual --123
17.select trunc(123,-1) from dual --120  

两个Date类型字段:计算这两个日期的时间差(分别以天,小时,分钟,秒,毫秒):

天:

ROUND(TO_NUMBER(END_DATE - START_DATE))

小时:

ROUND(TO_NUMBER(END_DATE - START_DATE) * 24)

分钟:

ROUND(TO_NUMBER(END_DATE - START_DATE) * 24 * 60)

秒:

ROUND(TO_NUMBER(END_DATE - START_DATE) * 24 * 60 * 60)

毫秒:

ROUND(TO_NUMBER(END_DATE - START_DATE) * 24 * 60 * 60 * 1000)

时间常用方法

oracle 向后取最近的5分钟

select trunc(sysdate,'hh24')+(to_char(sysdate,'mi')-mod(to_char(sysdate,'mi'),5))/60/24+5/60/24 from dual;  

 

延时,特定开始结束日期都可以从trunc获得(用从)

如: select trunc(sysdate,'yyyy') from dual 当年第一天, 再-1得到去年最后一天,trunc(trunc(sysdate,'yyyy')-1,'yy') 得到去年第一天

select  sysdate,sysdate-1 one_date,sysdate-1/24 one_hour,sysdate-1/(60*24) one_minute,sysdate-1/(60*24*60) one_second   from dual

select trunc(add_months(sysdate, -1), 'mm'),
       trunc(last_day(add_months(sysdate, -1)),'dd') last_day from dual;

(用to_char,to_date就过于麻烦了  select extract(year from sysdate)-1||'-01-01 00:00:00' start_time,concat(extract(year from sysdate)-1||'-12-'||to_char(LAST_DAY(sysdate),'dd '),'23:59:59') end_time   from dual)

 

Oracle SQL loader 

 LOAD DATA 

  INFILE 'test.txt' 

  APPEND  INTO TABLE dept 

  FIELDS TERMINATED BY ","

  (DEPTNO,DNAME,LOC)

 

SYSBASE

select  convert(datetime,convert(varchar(20),getdate(),111)+’ 00:00:00’)

--前25小时

select  convert(datetime,convert(varchar(20),dateadd(hour,-25,getdate()),111)+ ' '+convert(char(2),datepart(hh,dateadd(hour,-1,getdate())))||':00:00');

--此种写法00点取得是前1个小时

select convert(datetime,convert(varchar(20),dateadd(day,-1,'2014-11-28 00:00:00'),111)+ ' '+convert(char(2),datepart(hh,dateadd(hour,-1,'2014-11-28 00:00:00'

)))||':00:00')

查询当前日期起,以时、分、秒、天、周、月、季、年为间隔的日期 

covert 参数    108:时间   112:日期

时:select convert(char(8),dateadd(hour,1,getdate()),108) 

分:select convert(char(8),dateadd(minute,1,getdate()),108) 

秒:select convert(char(8),dateadd(second,1,getdate()),108) 

天:select convert(char(8),dateadd(day,1,getdate()),112) 

周:select convert(char(8),dateadd(week,1,getdate()),112) 

   dw 、week、weekday代表周几

月:select convert(char(8),dateadd(month,1,getdate()),112) 

季:select convert(char(8),dateadd(quarter,1,getdate()),112) 

年:select convert(char(8),dateadd(year,1,getdate()),112) 

取时间的某一个部分 

select datepart(yy,getdate()) --year 

select datepart(mm,getdate()) --month 

select datepart(dd,getdate()) --day 

select datepart(hh,getdate()) --hour 

select datepart(mi,getdate()) --min 

select datepart(ss,getdate()) --sec 

字符串时间 

select getdate() -- '03/11/12' 

select convert(char,getdate(),101) -- '09/27/2003' 

select convert(char,getdate(),102) -- '2003.11.12' 

select convert(char,getdate(),103) -- '27/09/2003' 

select convert(char,getdate(),104) -- '27.09.2003' 

select convert(char,getdate(),105) -- '27-09-2003' 

select convert(char,getdate(),106) -- '27 Sep 2003' 

select convert(char,getdate(),107) --'Sep 27, 2003' 

select convert(char,getdate(),108) --'11:16:06' 

select convert(char,getdate(),109) --'Sep 27 2003 11:16:28:746AM' 

select convert(char,getdate(),110) --'09-27-2003' 

select convert(char,getdate(),111) --'2003/09/27' 

select convert(char,getdate(),112) --'20030927' 

select rtrim(convert(char,getdate(),102))+' '+(convert(char,getdate(),108)) -- '2003.11.12 11:03:41' 

 

 

特定格式日期

select LEFT(convert(char(8),A.TIME_STAMP,112),4)+'-'+right(LEFT(convert(char(8),A.TIME_STAMP,112),6),2)+'-'+ right(LEFT(convert(char(8),A.TIME_STAMP,112),8),2)+' '+convert(char(8),A.TIME_STAMP,108) TIMESTR

select LEFT(convert(char(8),getdate(),112),4)+'-'+right(LEFT(convert(char(8),getdate(),112),6),2)+'-'+ right(LEFT(convert(char(8),getdate(),112),8),2) 

整数时间

select convert(int,convert(char(10),getdate(),112)) -- 20031112
select datepart(hh,getdate())*10000 + datepart(mi,getdate())*100 + datepart(ss,getdate()) -- 110646

 

dateadd()

取本月第一天,然后分别减一个月和一天就是上月第一天和最后一天 

select dateadd(mm,-1,convert(char(8),(datepart(yy,getdate())*10000+datepart(mm,getdate())*100+01)))
select dateadd(dd,-1,convert(char(8),(datepart(yy,getdate())*10000+datepart(mm,getdate())*100+01)))

5分钟

SELECT convert(char(2),datepart(MI,getdate())/5*5)

取本周第一天

select  DateAdd(day,1-(Case datepart(dw,Getdate())-1 when 0 then 7 else datepart(dw,GetDate())-1 end),GetDate())   dw 、week、weekday代表周几

select DateAdd(day,7-(Case datepart(dw,Getdate())-1 when 0 then 7 else datepart(dw,GetDate())-1 end),GetDate())

convert(varchar,datepart(year,getdate()))+'01'+'01'  --取今年第一天

DateAdd(day,-(datepart(day,getdate())-1),@Date1)  --取当月的第一天

dateadd(day,-1,DateAdd(day, -(datepart(day,dateadd(mm,1,getdate()))-1),dateadd(mm,1,getdate())))  --取当月的最后一天

dateadd(yy,-1,DateAdd(day,-(datepart(day,getdate())-1),getdate())) --取去年当月第一天

dateadd(day,-1,DateAdd(day, -(datepart(day,dateadd(yy,-1,dateadd(mm,1,getdate())))-1),dateadd(yy,-1,dateadd(mm,1,getdate()))))--取去年当月的最后一天

datename()函数同等于datepart

 

时间格式 "YYYY.MM.DD HH:MI:SS" 转换为 "YYYYMMDDHHMISS" 

declare @a datetime,@tmp varchar(20),@tmp1 varchar(20) 

select @a=convert(datetime,'2004.08.03 12:12:12') 

select @tmp=convert(char(10),@a,112) 

select @tmp 

select @tmp1=convert(char(10),datepart(hh,@a)*10000 + datepart(mi,@a)*100 + datepart(ss,@a)) 

select @tmp1 

select @tmp=@tmp+@tmp1 

select @tmp 

当月最后一天 

declare 

@tmpstr varchar(10) 

@mm int, 

@premm int, 

@curmmlastday varchar(10) 

begin 

select @mm=datepart(month,getdate())--当月 

select @premm=datepart(month,dateadd(month,-1,getdate())) --上个月 

if (@mm>=1 and @mm<=8) 

select @tmpstr=convert(char(4),datepart(year,getdate()))+'.0'+convert(char(1),datepart(month,dateadd(month,1,getdate())))+'.'+'01' 

else if (@mm>=9 and @mm<=11) 

select @tmpstr=convert(char(4),datepart(year,getdate()))+'.'+convert(char(2),datepart(month,dateadd(month,1,getdate())))+'.'+'01' 

else 

select @tmpstr=convert(char(4),datepart(year,dateadd(year,1,getdate())))+'.0'+convert(char(1),datepart(month,dateadd(month,1,getdate())))+'.'+'01' 

select @curmmlastday=convert(char(10),dateadd(day,-1,@tmpstr),102) --当月最后一天 

end 

字符串函数

http://blog.csdn.net/sunxing007/article/details/4292104

stuff

用expr2代替epxr1中start起始长为length的字符串

select  substring(stuff(objectName,charindex('-SYS',objectName),4,'1'),9,4) from PPM_Wap_KPI

 

Itrim()

 rtrim()返回删去尾随空白的指定表达式

select left('15425',2)='15'

select right('123456',2)='56'

substring('string',n,m)

返回字符串从第n个起长度为m的字符串

例如substring('iloveyou',2,4) 返回'love'

char_length('?????') 返回字符串的长度值, 例如 char_length('我爱你') 返回6. 中文字符一个占2个字节

char() 返回整数等值字符. 

count()

REPLICATE   

  以指定的次数重复字符表达式。     

  语法    REPLICATE   (   character_expression   ,   integer_expression   ) ,表达式2 只能是数字或者能转化为数字的字符串   

例:select Replicate('0','3') 返回 000  , select Replicate('0','-3')  返回null

 

 

TOP用法

select top 10 * from user order by id

isnull

select isnull(TYPE, 'UNKNOWN')


 

nullif

nullif(value1,value2)

解释: case when value1=value2 then null

       else value1 

       end 

   例: select nullif(2,2)

   返回值: null

       select nullif(1,2)

        返回值: 1

注意:value1何value2的数据类型必须兼容

isnull(value1,value2)

case when value1=null then value2 else value1 end

例:select isnull(null,0)=0

     select isnull(2,0)=2

 

 

datediff  round

  datediff(day,date1,date2)        date2与date1相差的天数,若date2在前,则返回值为负数

 round(number,n),四舍五入   例如 select round(123.155,2)=123.56

 

 

数学函数  

abs()返回当前数字的绝对值  例如 select abs(-2)=2

avg() 返回某列的平均值  

ceiling   返回大于或等于知道值的最小整数 /**ceiling,n.天花板, 最**/2

例如  select ceiling(9.1)=10  select ceiling(-9.1)

count(all|distinct|expression) 计算行数 

Sybase游标使用

CREATE PROCEDURE dbo.SP_NHM_CMNET_LINK_CITY_UPDATE

AS

    BEGIN

DECLARE @V_CUSTOM_NAMEVARCHAR(255)

DECLARE CUR_TMP CURSOR FOR SELECT LINK_UUID FROM dbo.NHM_CMNET_LINK_CITY

OPEN  CUR_TMP 

 

FETCH CUR_TMP  into @V_CUSTOM_NAME

    if (@@sqlstatus = 2) 

begin 

CLOSE CUR_TMP 

DEALLOCATE CURSOR CUR_TMP 

return -1 

    end 

    

 while(@@sqlstatus = 0) 

BEGIN

    update dbo.NHM_CMNET_LINK_CITY  set LINK_NAME=

     (

       select LINK_NAME from dbo.TM_LINK_INFORMATION where LINK_UUID=@V_CUSTOM_NAME

     ) where LINK_UUID=@V_CUSTOM_NAME

   commit

FETCH CUR_TMP  into @V_CUSTOM_NAME

   END

END

 

存储实例

CREATE PROCEDURE GetDataByLine

(

  --创建一个分页读取过程

  @SqlStr         varchar(16384), --SQL语句

  @FirstRec       int,  --页起始行

  @LastRec        int  --页结束行

)

AS

  DECLARE @dt varchar(10) --生成临时表的随机数

BEGIN

  --减少临时行结果

  set r                                    owcount @LastRec

  SELECT @dt= substring(convert(varchar, rand()), 3, 10) --一个字符型的随机数

  --将搜索结果放入临时表中,表名随机生成,在' FROM '前插入'INTO '+随机临时表名

  SELECT @SqlStr = stuff(@SqlStr, charindex(' FROM ', upper(@SqlStr)), 6 ,' INTO                                       tempdb..Lining' + @dt + ' FROM ')

  EXECUTE (@SqlStr)

  --为临时表增加id号

  SELECT @SqlStr = 'ALTER TABLE tempdb..Lining' + @dt + ' ADD TEMPDB_ID numeric(10) IDENTITY PRIMARY KEY'

  EXECUTE (@SqlStr)

  --计算临时表中              的记录数

  --SELECT @Sql                 Str = 'SELECT Count(*) From tempdb..Lining' + @dt

  --EXECUTE (@SqlStr)

  --选取记录号在起始行和结束行中间的记录

  SELECT @SqlStr = 'SELECT * FROM tempdb..Lining'+@dt+' WHERE TEMPDB_ID > ' + convert(varchar, @FirstRec) + 

                  ' and TEMPDB_ID                   <= ' + convert(varchar, @LastRec)

  EXECUTE (@SqlStr)

  --删除临时表

  SELECT @SqlStr = 'DROP TABLE tempdb..Lining'+@dt

  EXECUTE (@SqlStr)

END

 

 

 

 

 

MYSQL

 

Convert转换编码

select Convert(date_format(datetime, '%Y-%m-%d') using utf8) as datetime form tb 

用了date_format后在程序中查询出的结果为System.Byte[],而在数据库中查正常

 

DATE_FORMAT

DATE_FORMAT( DATE_ADD(SYSDATE(), INTERVAL "-4" DAY) ,'%Y-%m-%d 00:00:00') 

DATE_FORMAT( SYSDATE(), '%Y-%m-%d 00:00:00')

http://www.cnblogs.com/zeroone/archive/2010/05/05/1727659.html

日期函数

SELECT curdate();  取得当天

select now();   当前日期

 

括号中为当天时间的前一天,如果统计前几天就将括号中的’1’改成相应的天数。如果要算月或年,直接将day改为month或year即可

select date_sub(curdate(),interval 1 day);   取得前一天

SELECT YEAR(DATE_SUB(CURDATE(),INTERVAL 1 DAY));  取得前一天的年份

 

原文:http://www.51sdj.com/phpcms/picture/2009/0711/picture_133.html

 

sybase错误整理

 

Warning: A non-null value cannot be inserted into a
TIMESTAMP column by the user. The database timestamp value
has been inserted into the TIMESTAMP field instead

解决:Timestamp is only relevant if you use TSEQUAL. If you want a column
that you CAN insert/update, and view without code, just add a "user"
column (not an automatic one): datetime, date, small... etc

 --字段类型TIMESTAMP 更换为datetime

 

 多数据库的考虑

1.        字符串连接必须用“||”符号,不使用“+”。注意:在Oracle中一个null值与非null值连接,结果为非null值,在DB2SqlServer中相反。使用nvlnull转换为’’。

2.        通配符不能使用‘[a-c]%’这种形式,应写成如:select * from table_name where col1 like ‘[a]%’ OR col1 like ‘[b]%’ OR col1 like ‘[c]%’ 

3.        在对char类型比较时,要对列加上rtrim()函数,否则在Oracle中不会得到正确结果。例如若test表中的字段f1的长度为10,内有一个值为’aa’,的纪录,则语句select len(f1) from test;SqlServer的执行结果为2,在Oracle的执行结果为10

 

 


 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(数据库,sql,数据库)