sql常用关键字,函数...

时间:2019-01-23
本文章向大家介绍sql常用关键字,函数...,主要包括sql常用关键字,函数...使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

Distinct 去重

SELECT DISTINCT 列名称 FROM 表名称

 

oracle列转行 Listagg()

将查询到的 device_id 列转行:

select listagg(device_id,',') within GROUP (order by device_id) from T_DEVICE where userid = 1;

这是最基础的用法:

 

LISTAGG(XXX,XXX) WITHIN GROUP( ORDER BY XXX),

 

用法就像聚合函数一样,通过Group by语句,把每个Group的一个字段,拼接起来,非常方便。

 

 

同样是聚合函数,还有一个高级用法:

 

就是over(partition by XXX)

 

select population, 

nation, 

city, 

listagg(city,',') within GROUP (order by city) over (partition by nation) rank 

from temp

 

Mysql中的列转行group_concat()

select group_concat(num) from user

 

Case when

简单Case函数

CASE sex

WHEN '1' THEN '男'

WHEN '2' THEN '女'

ELSE '其他' END

 

--Case搜索函数

CASE WHEN sex = '1' THEN '男'

WHEN sex = '2' THEN '女'

ELSE '其他' END 

select 与 case结合使用最大的好处有两点,一是在显示查询结果时可以灵活的组织格式,二是有效避免了多次对同一个表或几个表的访问。

 

下面举个简单的例子来说明。例如表 students(id, name ,birthday, sex, grade),要求按每个年级统计男生和女生的数量各是多少,统计结果的表头为,年级,男生数量,女生数量。如果不用select case when,为了将男女数量并列显示,统计起来非常麻烦,先确定年级信息,再根据年级取男生数和女生数,而且很容易出错。

用select case when写法如下:

SELECT grade, COUNT (CASE WHEN sex = 1 THEN 1    

                            ELSE NULL

                        END) 男生数,

               COUNT (CASE WHEN sex = 2 THEN 1

                            ELSE NULL

                       END) 女生数

FROM students

GROUP BY grade;

 

Oracle分页

SELECT

       *

FROM

       (

              SELECT

                     a1.*, ROWNUM rn

              FROM

                     (

                            SELECT

                                   *

                            FROM

                                  t

                     ) a1

              WHERE

                     ROWNUM <= 25

       ) T

WHERE

       rn > 0

 

聚合函数的使用

 

--1:   AVG(DISTINCT|ALL)

ALL表示对所有的值求平均值,DISTINCT只对不同的值求平均值

 

SELECT AVG(SAL) FROM SCOTT.EMP;

 

SELECT AVG(DISTINCT SAL) FROM SCOTT.EMP;

 

 

--2:   MAX(DISTINCT|ALL)

求最大值,ALL表示对所有的值求最大值,DISTINCT表示对不同的值求最大值,相同的只取一次

(加不加查询结果一致,不知DISTINCT有什么用途,不同于AVG等聚合函数)

 

SELECT MAX(DISTINCT SAL) FROM SCOTT.EMP;

 

SELECT MAX(SAL) FROM SCOTT.EMP

 

--3:   MIN(DISTINCT|ALL)

求最小值,ALL表示对所有的值求最小值,DISTINCT表示对不同的值求最小值,相同的只取一次

 

SELECT MIN(SAL) FROM SCOTT.EMP;

 

SELECT MIN(DISTINCT SAL) FROM SCOTT.EMP;

 

--4:  STDDEV(distinct|all)

求标准差,ALL表示对所有的值求标准差,DISTINCT表示只对不同的值求标准差

 

SELECT STDDEV(SAL) FROM SCOTT.EMP;

 

SELECT STDDEV(DISTINCT SAL) FROM SCOTT.EMP;

 

--5:   VARIANCE(DISTINCT|ALL)

求协方差  ALL表示对所有的值求协方差,DISTINCT表示只对不同的值求协方差

 

SELECT VARIANCE(SAL) FROM SCOTT.EMP;

 

SELECT VARIANCE(DISTINCT SAL) FROM SCOTT.EMP;

 

--6:  SUM(DISTINCT|ALL)

求和  ALL表示对所有值求和,DISTINCT表示只对不同值求和(相同值只取一次)

 

SELECT SUM(SAL) FROM SCOTT.EMP;

 

SELECT SUM(DISTINCT SAL) FROM SCOTT.EMP;

 

--7:COUNT(DISTINCT|ALL)

求记录、数据个数。 ALL对所有记录,数组做统计, DISTINCT只对不同值统计(相同值只取一次)

 

SELECT COUNT(SAL) FROM SCOTT.EMP;

 

SELECT COUNT(DISTINCT SAL) FROM SCOTT.EMP; 

 

----8: MEDIAN

求中位数

SELECT MEDIAN(SAL) FROM SCOTT.EMP;

SELECT MEDIAN(DISTINCT SAL) FROM SCOTT.EMP;  --错误:DISTINCT 选项在此函数中禁用。

 

开窗函数

ROW_NUMBER就是直接排序,每个行号唯一且连续。
RANK就是并列排序,遇到值相同的,行号并列。例如:1,2,3,3,5
DENSE_RANK也是并列排序,值相同,行号并列。例如:1,2,3,3,4
比较不常用,NTLE(6)就是,将所有的列分为6组,比如这边是10列,然后10/6=1(于是每组为1)...余数为4(前面4组+1):1,1,2,2,3,3,4,4,5,6

常用分析函数:(最常用的应该是1.2.3 的排序)
1、row_number() over(partition by ... order by ...)
2、rank() over(partition by ... order by ...)
3、dense_rank() over(partition by ... order by ...)
4、count() over(partition by ... order by ...)
5、max() over(partition by ... order by ...)
6、min() over(partition by ... order by ...)
7、sum() over(partition by ... order by ...)
8、avg() over(partition by ... order by ...)
9、first_value() over(partition by ... order by ...)
10、last_value() over(partition by ... order by ...)
11、lag() over(partition by ... order by ...)
12、lead() over(partition by ... order by ...)
lag 和lead 可以 获取结果集中,按一定排序所排列的当前行的上下相邻若干offset 的某个行的某个列(不用结果集的自关联);
lag ,lead 分别是向前,向后;
lag 和lead 有三个参数,第一个参数是列名,第二个参数是偏移的offset,第三个参数是 超出记录窗口时的默认值)

 

Oracle时间

当前时间的 月的第一天

select trunc(add_months(last_day(sysdate), -1) + 1) from dual;

当前时间的 月的最后一天

select last_day(to_date('20181111', 'yyyymmdd')) from dual;