数据库高级数据过滤之SQL操作符与SELECT子句

高级数据过滤

AND操作符

要通过不止一个列进行果过滤,可以使用AND操作符对WHERE子句附加条件,用在WHERE子句中的关键字

OR 操作符

OR操作符与AND操作符正好相反,它告诉DBMS检索匹配任一条件的行,事实上,许多DBMSORWHERE 子句的第一个条件得到满足的情况下就不再计算第二个条件了(在第一个条件满足时,不管第二个条件是否满足,相应的行都将被检索出来)

IN 操作符

In操作符用来指定条件范围,范围中的每个条件都可以进行匹配,in取一组逗号分隔,括在圆括号中的合法值IN 操作符允许我们在 WHERE 子句中规定多个值。

SQL  IN 语法 

SELECT column_name(s) FROM table_nameWHERE column_nam e IN (value1,value2,...)

IN 操作符实例

SELECT prof_name ,prod_price FROM  Products WHERE vend_id IN(‘DLL01’, ’BRSo1’)ORDER BY prod_name

SELECT 语句检索由供应商DDL01BRS01制造的所有产品,IN操作符后跟由逗号分隔的合法值,这些值必须在圆括号中.

你会猜测IN 操作符完成了与OR相同的功能,恭喜你答对了,下面的SQL语句完成了与上面的例子相同的工作,

SELECT prod_name,prod_price FROM Products WHERE vend_id=’DDL01’ OR vend_id=’BRS01’ ORDER BY prod_name;

in =的区别

select name from student where name in ('zhang','wang','li','zhao');

select name from student where name='zhang' or name='li' or name='wang' or name='zhao'

的结果是相同的。

 

为什么使用IN操作符呢,优点如下:

1.IN操作符的语法更清楚直观,

2.IN的最大优点是可以包含其他的SELECT语句,能够更动态地建立WHERE子句,

NOT操作符

WHERE子句中的NOT操作符有且只有一个功能,那就是否定其后所跟的任何条件,因为NOT从不单独使用,(他总是与其他操作符一起使用),所以了他的语法与其他操作符有所不同,NOT关键字可以用在要过滤的列强,而不仅是在其后.

实例:

列出除了DLL01之外的所有供应商制造的产品

SELECT prod_name FROM Products WHERE NOT vend_id=’DLL01’ ORDER BY prod_name

这里的NOT否定跟在其后的条件,因此,DBMS不是匹配vend_idDLL01,而是匹配非DLL01之外的所有东西上面的例子也可以使用<>操作符完成

SELECT prod_name FROM Products WHERE NOT vend_id<>’DLL01’ ORDER BY prod_name

在简单的WHERE子句中NOT没有什么优势,但是在复杂的子句中NOT是非常有用的,例如,在与IN操作符联合使用时,NOT可以非常简单地找出与条件列表不匹配的行

 

any、all、exists 的使用

1. 数据表

有如下数据表:StudentInfo 学员信息表,表数据如图1 所示:

ID

NAME

SCORE

CLASSNAME

1

张青青

78

S1101

2

李红

54

S1101

3

顾小强

86

S1101

4

陈乔

34

S1102

5

韩伟

99

S1102

 

图1 学员信息表数据

其中,ID 代表学员编号,NAME 为学员姓名,SCORE 为学员考试成绩,CLASSNAME 为学员所在的班级名称。

2. any 的使用

编写 sql 语句查询:S1101 班哪些学生的成绩高于S1102 班的最低成绩

SELECT NAME FROM studentInfo WHERE classname='S1101' AND score >(SELECT MIN(score) FROM studentInfo WHERE classname='S1102');

除此之外,我们还可以使用any:

SELECT NAME FROM studentInfo WHERE classname='S1101' AND score >ANY(SELECT score FROM studentInfo WHERE classname='S1102');

3. all 的使用

编写sql 语句查询:S1101 班哪些学生的成绩高于S1102 班的最高成绩

SELECT NAME FROM studentInfo WHERE classname='S1101' AND score >(SELECT MAX(score) FROM studentInfo WHERE classname='S1102');

除此之外,我们还可以使用all:

SELECT NAME FROM studentInfo WHERE classname='S1101' AND score >ALL(SELECT score FROM studentInfo WHERE classname='S1102');

4. exists 的使用

EXISTS 的作用比较简单,它只关注它后面的子查询返没返回值,而不在乎返回多少。如果返回,则整个表达式就为真,否则为假。NOT EXISTS 关键字则和EXISTS 作用相反。

假设要查询有没有成绩为 100 的学生,如果有,则将所有学生的成绩都输出,如果没有,

则什么都不输出,我们使用EXISTS 实现,如下:

SELECT name,score FROM studentInfo WHERE EXISTS(SELECT * FROM studentInfo WHERE score=100);

INEXISTS区别

in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。

如果查询的两个表大小相当,那么用inexists差别不大。

 

如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in

 

例如:表A(小表),表B(大表)

1

select * from A where cc in (select cc from B)

效率低,用到了A表上cc列的索引;

select * from A where exists(select cc from B where cc=A.cc)

效率高,用到了B表上cc列的索引。

相反的

2

select * from B where cc in (select cc from A)

效率高,用到了B表上cc列的索引;

select * from B where exists(select cc from A where cc=B.cc)

效率低,用到了A表上cc列的索引。

not in not exists

如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;

not extsts 的子查询依然能用到表上的索引。

所以无论那个表大,用not exists都比not in要快。

 

(记录合并)unionunion all 的区别

 

在数据库中,unionunion all关键字都是将两个结果集合并为一个,但这两者从使用和效率上来说都有所不同。

 

union在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果。

如:

 select * from test_union1

   union

 select * from test_union2

      这个SQL在运行时先取出两个表的结果,再用排序空间进行排序删除重复的记录,最后返回结果集,如果表数据量大的话可能会导致用磁盘进行排序。

    union all只是简单的将两个结果合并后就返回。这样,如果返回的两个结果集中有重复的数据,那么返回的结果集就会包含重复的数据了。

     从效率上说,union all要比union快很多,所以,如果可以确认合并的两个结果集中不包含重复的数据的话,那么就使用union all,如下:

select * from test_union1

union all

select * from test_union2

 

 

 使用 union/union all 组合查询的结果集有两个最基本的规则:

 

1。所有查询中的列数和列的顺序必须相同。

 

2。数据类型必须兼容

 

 

 

SELECT子句

Group By子句

首先讲讲GROUP BY 子句语法:

sql语句Group By用法一则
如果我们的需求变成是要算出每一间店 (store_name) 的营业额 (sales),那怎么办呢?在这个情况下,我们要做到两件事:

第一,我们对于 store_name 及 Sales 这两个栏位都要选出。

第二,我们需要确认所有的 sales 都要依照各个 store_name 来分开算。这个语法为:   
SELECT "栏位1", SUM("栏位2") FROM "表格名" GROUP BY "栏位1"   

示范
Store_Information 表

store_name

Sales

Date

Los Angeles

$1500

Jan-05-1999

San Diego

$250

Jan-07-1999

Los Angeles

$300

Jan-08-1999

Boston

$700

Jan-08-1999

 

我们就打入,                                 

SELECT store_name, SUM(Sales)    FROM  Store_Information  GROUP BY store_name   

结果

store_name

SUM(Sales)

Los Angeles

$1800

San Diego

$250

Boston

$700

 


例子2
SELECT   column1, SUM(column2)  FROM   "list-of-tables"  GROUP BY "column-list";

例子如下:

一个销售表sales:

workername

salemoney

a1

3000

a2

2000

a3

1000

a2

3000

 

1.sql要求,查询每个员工的总销售总额:

SELECT  workername,SUM(salemoney)  FROM  sales GROUP BY  workername

2.sql要求,查询总销售额最大的员工姓名跟销售额:

SELECT  workername,MAX(salemoney) FROM  sales GROUP BY workername

3.sql要求,查询总销售额大于等于2000的员工姓名跟销售额:

SELECT workername, SUM(salemoney)  FROM sales GROUP BY workername HAVING SUM(salemoney)>=2000


何时使用GROUP BY(心得)

一般业务要求出现 大于,等于,小于,最大,最小等范围词语,具体是使用where 还是having,要看是过滤行还是分组,也可同时使用where having

找出具有两个订单以上的顾客

SELECT cust_id ,COUNT(*) AS orders FROM Orders GROUP BYcust_id HAVING COUNT(*) >=2

找出具有两个以上产品且其价格大于等于4的供应商

SELECT vend_id ,count(*) AS num_prods FROM Products WHERE  pro_price>=4 GROUP BY vend_id HAVING COUNT(*)>=2

先找出 产品价格大于等于4的产品 再以供应商分组,返回供应商产品个数信息,一般having再以返回的信息作为条件对分组在进行过滤

 

 

 


group by 有一个原则,就是 select 后面的所有列中,没有使用聚合函数的列,必须出现在 group by 后面 ,select 列表中指定的列要么是group by 子句中指定的列,要么包含聚组函数

 

说白了就是select 所取出的字段 在分组里必须有,但是排除被合计的字段,比如

select a,b,c from table group by a,b,c这里 group by 里 必须有a,b,c
如果改成 select a,b,sum(c) from table groupby a,b,这里 因为c被合计了 所以按照a,b分组就可以了

同样的合计函数还包括max count 等等!

group by 除聚合函数外,sum,其他函数,decode,所修饰的数据库字段都要在group  by 后体现到

假如一个公司下面有五个工厂,以公司id和工厂id进行group by,那么出现的结果将会以最小单位来分组,即五条公司名称相同但是工厂名称不同的记录,

 

 

Having子句

     在select 语句中可以使用group by 子句将查询出的行划分成组,然后,使用聚组函数返回每一个组的汇总信息,另外,可以使用having子句过滤分组,规定包括哪些分组,排除哪些分组,

   当在gropu by 子句中使用having 子句时,查询结果中只返回满足having条件的组。在一个sql语句中可以有where子句和having子句。having 与where 子句类似,均用于设置限定条件,where过滤指定的行,having过滤指定的组,having 子句可以出现聚组函数,在where 子句中不能使用聚组函数。

 SELECT deptno,SUM(sal)  FROM  emp 

WHERE sal>1200

GROUP BY   deptno  

HAVING  SUM(sal)>8500 

  ORDER BY deptno;

一般使用GROUP BY子句时,应该也给出ORDER BY 子句,这是保证数据正确排序的唯一方法
   where 子句的作用是在对查询结果进行分组前,将不符合where条件的行去掉,即在分组之前过滤数据,条件中不能包含聚组函数,使用where条件显示特定的行。
   having 子句的作用是筛选满足条件的组,即在分组之后过滤数据,条件中经常包含聚组函数,使用having 条件显示特定的组,也可以使用多个分组标准进行分组。

 查询每个部门的每种职位的雇员数
SELECT  deptno,job,COUNT(*) FROM emp GROUP BY  deptno,job

查出每个供应商的产品数

SELECT vend_id ,COUNT(*) AS num_prods FROM Products GROUP BY vend_id

结果:

vend_id

num_prods

BRS01

3

DLL01

4

FNG01

2

GRUOP BY 子句指示DBMSvend_id排序并分组数据,这就会对每个vend_id而不是整个表计算num_prods一次,从输出中可以看出,供应商BRS013个产品,供应商DLL014个产品,而供应商FNG012个产品

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
一、SQL 结构化查询语言 包括DDL(数据定义语言)、DCL(数据控制语言)、 DQL(数据查询语言)、DML(数据操纵语言) 二、SQL的特点 SQL 语句不区分大小写 SQL 语句能输入一行或多行 关键字不能整行缩写或分离 子句通常被放置在分开的行上 缩进可提高可读性 在SQL 开发工具,SQL 语句能选择分号结束(;) .当你运行多个SQL 语句的时候,需要分号 在SQL*Plus中, 你要用一个分号结束每个SQL 语句.(;) 三、SQL*PLUS特征: 字符日期左对齐 数字右对对齐 列名默认大写 SQL PLUS 自己的命令不需以分号“;”结束 四、SQL查询时,数字和日期类型的数据可用算术运算符 + 加 - 减 * 乘 / 除 ( ) 用于改变运算符的优先级 五、空值 空值一般用NULL表示 一般表示未知的、不确定的值,也不是空格 一般运算符与其进行运算时,都会为空 空不与任何值相等 表示某个列为空用:IS NULL 不能使用COMM=NULL这种形式 某个列不为空:IS NOT NULL 不能使用COMM != NULL 这种形式 空值在作升序排列时,空值会放到最后。 相反作降序排列时,空值会放在最前。 空值作逻辑运算时: AND运算: F AND F =F F AND T =F F AND NULL =F T AND F =F T AND T =T T AND NULL IS NULL NULL AND F =F NULL AND T IS NULL NULL AND NULL IS NULL 就是说AND的优先级是:F ->NULL ->T OR运算: T OR T =T T OR F =T T OR NULL =T F OR T =T F OR F =F F OR NULL IS NULL NULL OR T =T NULL OR F IS NULL NULL OR NULL IS NULL OR运算优先级:T ->NULL ->F NOT运算: NOT T =F NOT F =T NOT NULL IS NULL 与空值相关的函数: NVL 函数 格式:NVL(表达式1,表达式2) 作用:测试表达式的值,如果表达式1为空,则返回表达式2的值;不为空,返回表达式1的值。 NVL2 函数 格式:NVL2(表达式1,表达式2,表达式3) 作用:测试表达式的值,表达式1不为空,返回表达式2的值,如果为空,则返回表达式3的值。 NULLIF 相等为空 格式:NULLIF (表达式1,表达式2) 作用:比较表达式1和表达式2的值,如果两个相等则返回为空,否则返回表达式1的值。 COALESCE 找非空 格式:COALESCE (表达式1,表达式2,表达式3,...,表达式n) 作用:返回第一个不为空的值,如果所有的都为空,则返回NULL。 六、SELECT语句的用法 SELECT *|{[DISTINCT] column|expression [alias],...} FROM table; 七、演示 */ --选择所有字段 SQL> SET LINESIZE 200 SQL> SELECT * FROM SCOTT.EMP; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- --------- ---------- ---------- ---------- 7369 SMITH CLERK 7902 17-DEC-80 800 20 7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30 7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30 7566 JONES MANAGER 7839 02-APR-81 2975 20 7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30 --选择部分字段 SQL> SELECT EMPNO,ENAME,SAL FROM SCOTT.EMP; EMPNO ENAME SAL ---------- ---------- ---------- 7369 SMITH 800 7499 ALLEN 1600 7521 WARD 1250 --算术加减运算 SQL> SELECT EMPNO,ENAME,SAL + 300 FROM SCOTT.EMP; EMPNO ENAME SAL+300 ---------- ---------- ---------- 7369 SMITH 1100 7499 ALLEN 1900 7521 WARD 1550 --优先级 SQL> SELECT EMPNO,ENAME,12 * (SAL + 300) FROM SCOTT.EMP; EMPNO ENAME 12*(SAL+300) ---------- ---------- ------------ 7369 SMITH 13200 7499 ALLEN 22800 7521 WARD 18600 SQL> SELECT EMPNO,ENAME,12 * SAL + 300 FROM SCOTT.EMP; EMPNO ENAME 12*SAL+300 ---------- ---------- ---------- 7369 SMITH 9900 7499 ALLEN 19500 7521 WARD 15300 --NULL,记录中COMM存在为NULL的情况 SQL> SELECT EMPNO,ENAME,SAL,COMM FROM SCOTT.EMP; EMPNO ENAME SAL COMM ---------- ---------- ---------- ---------- 7369 SMITH 800 7499 ALLEN 1600 300 7521 WARD 1250 500 7566 JONES 2975 --与NULL运算,结果为NULL SQL> SELECT EMPNO,ENAME,SAL,COMM + 300 FROM SCOTT.EMP; EMPNO ENAME SAL COMM+300 ---------- ---------- ---------- ---------- 7369 SMITH 800 7499 ALLEN 1600 600 7521 WARD 1250 800 7566 JONES 2975 --将COMM不为NULL的记录的COMM乘以 SQL> SELECT EMPNO,ENAME,SAL,COMM * 12 FROM SCOTT.EMP WHERE COMM IS NOT NULL EMPNO ENAME SAL COMM*12 ---------- ---------- ---------- ---------- 7499 ALLEN 1600 3600 7521 WARD 1250 6000 7654 MARTIN 1250 16800 7844 TURNER 1500 0 --字段别名,字段后用AS 别名,AS可以省略 SQL> SELECT EMPNO,ENAME AS EmpName,SAL Salary FROM SCOTT.EMP; EMPNO EMPNAME SALARY ---------- ---------- ---------- 7369 SMITH 800 7499 ALLEN 1600 7521 WARD 1250 7566 JONES 2975 --DISTINCT,过滤重复行 SQL> SELECT DISTINCT EMPNO,ENAME FROM SCOTT.EMP; --连接操作符,通过二个垂直的条描述(||),注意,日期和文字数值一定嵌入在单引号里面 SQL> SELECT EMPNO,ENAME || ' IS A ' ||JOB AS POSITION FROM SCOTT.EMP; EMPNO POSITION ---------- ------------------------- 7369 SMITH IS A CLERK 7499 ALLEN IS A SALESMAN 7521 WARD IS A SALESMAN --DESC table_name,显示表结构信息 SQL> DESC SCOTT.EMP Name Null? Type ----------------------------------------- -------- ---------------------------- EMPNO NOT NULL NUMBER(4) ENAME VARCHAR2(10) JOB VARCHAR2(9) MGR NUMBER(4) HIREDATE DATE SAL NUMBER(7,2) COMM NUMBER(7,2) DEPTNO NUMBER(2) --NVL的用法 SQL> SELECT EMPNO,ENAME,NVL(TO_CHAR(COMM),'Not Applicable') FROM SCOTT.EMP; EMPNO ENAME NVL(TO_CHAR(COMM),'NOTAPPLICABLE') ---------- ---------- ---------------------------------------- 7369 SMITH Not Applicable 7499 ALLEN 300 7521 WARD 500 7566 JONES Not Applicable --NVL2的用法 SQL> SELECT empno,ename,sal,NVL2(TO_CHAR(comm),12 * (sal + comm),sal) AS Income FROM scott.emp; EMPNO ENAME SAL INCOME ---------- ---------- ---------- ---------- 7369 SMITH 800 800 7499 ALLEN 1600 22800 7521 WARD 1250 21000 7566 JONES 2975 2975 --NULLIF的用法 --等价于CASE WHEN expr1 = expr2 THEN NULL ELSE expr1 END SQL> SELECT e.last_name, NULLIF(e.job_id, j.job_id) "Old Job ID" 2 FROM hr.employees e, hr.job_history j 3 WHERE e.employee_id = j.employee_id 4 ORDER BY last_name, "Old Job ID"; LAST_NAME Old Job ID ------------------------- ---------- De Haan AD_VP Hartstein MK_MAN Kaufling ST_MAN Kochhar AD_VP Kochhar AD_VP Raphaely PU_MAN Taylor SA_REP Taylor Whalen AD_ASST Whalen --下面是使用CASE WHEN的等价用法 SQL> SELECT e.last_name, CASE WHEN e.job_id = j.job_id THEN NULL ELSE e.job_id END AS "Old Job ID" 2 FROM hr.employees e, hr.job_history j 3 WHERE e.employee_id = j.employee_id 4 ORDER BY last_name, "Old Job ID"; LAST_NAME Old Job ID ------------------------- ---------- De Haan AD_VP Hartstein MK_MAN Kaufling ST_MAN Kochhar AD_VP Kochhar AD_VP Raphaely PU_MAN Taylor SA_REP Taylor Whalen AD_ASST Whalen --COALESCE的用法 --当COALESCE(exp1,exp2)包含两个表达式时,等价于CASE WHEN exp1 IS NOT NULL THEN exp1 ELSE exp2 END --COALESCE (expr1, expr2, ..., exprn), for n>=3 --当n >= 3时,等价于 --CASE WHEN expr1 IS NOT NULL THEN expr1 -- ELSE COALESCE (expr2, ..., exprn) END SQL> SELECT product_id, list_price, min_price, 2 COALESCE(0.9*list_price, min_price, 5) "Sale" 3 FROM oe.product_information 4 WHERE supplier_id = 102050 5 ORDER BY product_id, list_price, min_price, "Sale" PRODUCT_ID LIST_PRICE MIN_PRICE Sale ---------- ---------- ---------- ---------- 1769 48 43.2 1770 73 73 2378 305 247 274.5 2382 850 731 765 3355 5 八、更多

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

晨港飞燕

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

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

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

打赏作者

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

抵扣说明:

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

余额充值