第三章 SQL数据库开发--TSQL--select查询

2024-03-05 08:38

本文主要是介绍第三章 SQL数据库开发--TSQL--select查询,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

第三章 SQL数据库开发--TSQL--select查询

 

3.1 select语法与逻辑处理顺序与谓词运算符优先级

3.1.1 select语法

SELECT [ ALL | DISTINCT ]  

    [TOP ( expression ) [PERCENT] [ WITH TIES ] ]  

    < select_list >  

    [ INTO new_table ]  

    [ FROM { <table_source> } [ ,...n ] ]  

    [ WHERE <search_condition> ]  

[ <GROUP BY> ]  

[ HAVING < search_condition > ] 

[ORDER BY…]

3.1.2  select逻辑处理顺序

1 FROM

2 ON

3 JOIN

4 WHERE

5 GROUP BY

6 WITH CUBE 或 WITH ROLLUP

7 HAVING

8 SELECT

9  DISTINCT

10 ORDER BY

 

3.1.3 select谓词运算符优先级

谓词用于 WHERE 子句和 HAVING 子句的搜索条件中

级别   运算符

0  ()

1  ~(位非)

2  *(乘)、/(除)、%(取模)

3  +(正)、-(负)、+(加)、+(串联)、-(减)、&(位与)、^(位异或)、|(位或)

4  =、>、<、>=、<=、<>、!=、!>、!<(比较运算符)

5  NOT

6  AND

7  ALL、ANY、BETWEEN、IN、LIKE、OR、SOME

8  =(赋值)

 

3.2 TOP限制结果集与DISTINCT消除重复行

3.2.1 TOP限制结果集

TOP限制10输出

SELECT top 10 mid,transoccurtime FROM L05_EXIT_TRAN where transoccurtime>'2018-05-01' order by transoccurtime desc

 

TOP限制1%输出

SELECT top 1 PERCENT mid,transoccurtime FROM L05_EXIT_TRAN where transoccurtime>'2018-05-01' order by transoccurtime desc

3.2.2 DISTINCT消除重复行

set rowcount 100

SELECT  distinct (shiftbegintime) FROM L05_EXIT_TRAN where transoccurtime>'2018-05-01' order by shiftbegintime desc

 

3.3 在选择列上使用常量,函数,别名

3.3.1 使用常量

SELECT user_name,'姓名' as 常量列 FROM A70_USERS_ZH

张春生 姓名

朱艳平 姓名

郅立强 姓名

王金华 姓名

 

3.3.2 使用函数

SELECT top 100 year(ac_when) FROM P01_TOD_INDEX;

 

3.3.3 别名

注意事项:定义了表别名以后,在语句中对该表的引用,都必须使用别名

SELECT top 20 l05.transoccurtime FROM L05_EXIT_TRAN as l05

SELECT top 20 l05.transoccurtime as 交易时间 FROM L05_EXIT_TRAN as l05

3.4 使用where筛选

3.4.1 使用谓词运算符过滤数据

交易时间大于2018-05-01,输出10行

SELECT  top 10 * FROM L05_EXIT_TRAN where transoccurtime>'2018-05-01' order by shiftbegintime desc

 

交易时间大于2018-05-01,或者mid<0 输出10行

 

SELECT  top 10 * FROM L05_EXIT_TRAN where transoccurtime>'2018-05-01' or mid<0 order by shiftbegintime

-43341886603952831      1899-12-30 00:00:00

-43341882293519868      1899-12-30 00:00:00

-43341882283112241      1899-12-30 00:00:00

 

Between ….and  中间的条件是包含。5月1日至5月10日

SELECT  top 10 mid,shiftbegintime FROM L05_EXIT_TRAN where transoccurtime between  '2018-05-01' and '2018-05-10' order by shiftbegintime desc

3.4.2 使用like进行模糊查询

通配符

含义

%

代表任意字符

_下划线

代表单个字符

[]

指定范围如[a-e]a到e [a,f]a和f

[^]

不包含字符

 

SELECT * FROM A70_USERS_ZH where user_name like '王[欢,磊]'

王磊

王欢

 

SELECT user_name FROM A70_USERS_ZH where user_name like '王[^欢,磊]'

王宇

王俊

王晨

 

SELECT * FROM A70_USERS_ZH where user_num like '1600[5-9]%'

16005001

16005002

16005003

16005004

16005005

 

3.4.3 如何使用null

当指定null条件的时候,使用is null 或者is not null

SELECT * FROM A72_ROLES_DOWN where role_com is not null

0    11   分中心稽查员    稽查帐务     2     0

0    13   9092      9092      2     0

 

3.5 子查询与嵌套查询

3.5.1 子查询与嵌套查询定义与语法

子查询是一个嵌套在它可以使一个 SELECT、SELECT...INTO 语句、INSERT语句、DELETE 语句、 UPDATE 语句或其他子查询中的查询。子查询嵌套在查询内部,且必须始终出现在圆括号内。

Select * (子查询T2) from T1 where 查询表达式 in或者 exists子查询。

                        where 查询表达式 比较运算符ANY|ALL(子查询)

嵌套查询又称子查询,是指在父查询的where条件语句中再插入一个子查询语句,连接查询都可以用子查询完成,反之不然。在SQL语言中,一个 SELECT-FROM-WHERE 语句称为一个查询块。将一个查询块嵌套在另一个查询块的 WHERE 子句或 HAVING 短语的条件中的查询称为 嵌套查询

 

 

3.5.2 子查询与嵌套查询事例

3.5.2.1 子查询在select后

SELECT table_id,count(*) 下发数量,(SELECT count(*) FROM A37_Lane_Info) 收费节点数 FROM PARAM_SEND_LANE where version=1811040000220717 and sfrom=0 group by table_id;

 

3.5.2.2 子查询在where后

 

SELECT table_id,count(*) 下发数量,(SELECT count(*) FROM A37_Lane_Info) 收费节点数 FROM PARAM_SEND_LANE where version in (

SELECT version_id FROM A93_VERSION_STATE_ZH where table_id>150000 and state=5 and increment=0) and sfrom=0 group by table_id order by 下发数量 ;

 

 

3.5.3 EXISTS关键字与IN

 语法 EXISTS表达式 subquery子查询  如果子查询包含任何行,则返回 TRUE。

   EXISTS是可接受一个查询作为输入,如果子查询返回任意行,TRUE,否则为FALSE。

 

IN 确定给定的值是否与子查询或列表中的值相匹配。in在查询的时候,首先查询子查询的表,然后将内表值和外表做一个笛卡尔积,然后按照条件进行筛选。所以相对内表比较小的时候,in的速度较快。

EXISTS 指定一个子查询,检测行的存在。遍历循环外表,然后看外表中的记录有没有和内表的数据一样的。匹配上就将结果放入结果集中。

 

in 和 exists的区别: 如果子查询得出的结果集记录较少,主查询中的表较大且又有索引时应该用in, 反之如果外层的主查询记录较少,子查询中的表大,又有索引时使用exists。其实我们区分in和exists主要是造成了驱动顺序的改变(这是性能变化的关键),如果是exists,那么以外层表为驱动表,先被访问,如果是IN,那么先执行子查询。

 In 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。一直以来认为exists比in效率高的说法是不准确的。

 

 

 

SELECT TOP 1000 * FROM L05_EXIT_TRAN where transoccurtime>'2017-11-01'  and transoccurtime<'2017-11-28' and operatorid in (SELECT user_id FROM A70_USERS_ZH where user_num= 15001924 )耗时11

 

 

SELECT TOP 1000 * FROM L05_EXIT_TRAN l05 where l05.transoccurtime>'2017-11-01'  and l05.transoccurtime<'2017-11-28' and EXISTS (SELECT a70.user_id FROM A70_USERS_ZH a70 where a70.user_num=15001924 and a70.user_id=l05.operatorID )

耗时2分钟

 

3.5.4 对于ALL,SOME,ANY的理解

运算符

含义

ALL

如果一组的比较都为 TRUE,那么就为 TRUE

SOME

如果在一组比较中,有些为 TRUE,那么就为 TRUE

ANY

如果一组的比较中任何一个为 TRUE,那么就为 TRUE

  

  ALL 比较标量值和单列集中的值

    语法 scalar_expression表达式 { = | <> | != | > | >= | !> | < | <= | !< } ALL ( subquery子查询 )

     SOME | ANY (Transact-SQL) 比较标量值和单列集中的值。 SOME ANY 是等效的。

    语法 scalar_expression 表达式{ = | < > | ! = | > | > = | ! > | < | < = | ! < }

     { SOME | ANY } ( subquery子查询  )

 

SELECT * FROM A70_USERS_ZH where user_id  > all (select user_id  from A74_USER_ROLE where role_id>3)  USER_id大于最大值

TI 表有ID1,2,3,4

以下查询返回 TRUE,因为 3 小于表中的某些值。

复制

IF 3 < SOME (SELECT ID FROM T1)

PRINT 'TRUE'

ELSE

PRINT 'FALSE' ;

以下查询返回 FALSE,因为 3 并不小于表中的所有值。

复制

IF 3 < ALL (SELECT ID FROM T1)

PRINT 'TRUE'

ELSE

PRINT 'FALSE' ;

 

 

 

3.6 order by对结果排序

对于null排序处理,是无穷小。Order by默认升序ASC不用写,如果使用降序使用DESC。

单列排序

SELECT  attach_id,user_name FROM A70_USERS_ZH order by attach_id

多列排序

SELECT  attach_id,user_num,user_name FROM A70_USERS_ZH order by attach_id desc,user_num

1001136      7001003       郑彤染

1001136      7001004       杨学培

1001136      7001007       张天杰

1001136      7001008       何敏

1001136      7001009       黄丽强

1001136      7001012       郑健

3.7 使用GROUP BY 子句和聚集函数进行分组

3.7.1 GROUP BY使用基础

聚集函数

AVG() 返回某列的平均值

COUNT()返回某列的行数

MAX() 返回某列的最大值

MIN() 返回某列的最小值

SUM()返回某列值之和

 

查询7月以后,出口广场的车流量

SELECT a36.organ_name as 广场,count(*) as 车流量 FROM L05_EXIT_TRAN as l05,A36_ORGAN as a36 where l05.transoccurtime>'2018-07-01' and  l05.plaza_id=a36.organ_id group by a36.organ_name order by 车流量 desc

 

西红门主站进京出      3751926

榆垡南出京出           1660982

金华寺站出京出           667890

庞各庄站出京出           625676

西红门南桥进京出2        579101

海子角站进京出           546598

天宫院站出京出           531863

3.7.2 HAVING子句筛选分组后的数据

Having与where子句功能相同,都是对数据进行筛选,不同的是,where是对分组之前的数据筛选,having是对分组后的数据筛选,having可以使用聚合函数或者其他表达式,where 子句不能。进行先使用where子句,where子句性能好

查询7月以后,出口广场的车流量大于6万的广场

SELECT a36.organ_name as 广场,count(*) as 车流量 FROM L05_EXIT_TRAN as l05,A36_ORGAN as a36 where l05.transoccurtime>'2018-07-01' and  l05.plaza_id=a36.organ_id group by a36.organ_name having count(*)>600000 order by 车流量 desc

西红门主站进京出  3751926

榆垡南出京出   1660982

金华寺站出京出      667890

庞各庄站出京出      625676

 

 

3.7.3 Where 和having比较

Where 筛选good

SELECT  a36.organ_name as 广场,count(*) as 车流量 FROM L05_EXIT_TRAN as l05,A36_ORGAN as a36 where l05.transoccurtime>'2018-07-01' and l05.plaza_id>100100 and l05.plaza_id=a36.organ_id group by a36.organ_name order by 车流量 desc

Having 筛选bad

SELECT  l05.plaza_id as 广场,count(*) as 车流量 FROM L05_EXIT_TRAN as l05,A36_ORGAN as a36 where l05.transoccurtime>'2018-07-01' and   l05.plaza_id=a36.organ_id group by l05.plaza_id having l05.plaza_id>100100 order by 车流量 desc

Where 子句过滤后,然后对更少的数据分组,第二个是分组后,过滤。当然是where子句性能好。

 

3.7.4 NO-GROUP BY ROLLUPCUBE  没有弄明白

 

3.8 COMPUTE (Transact-SQL) 以后会舍弃不用

生成合计作为附加的汇总列出现在结果集的最后。当与 BY 一起使用时,COMPUTE 子句在结果集内生成控制中断和小计。可在同一查询内指定 COMPUTE BY COMPUTE

语法

[ COMPUTE

    { { AVG | COUNT | MAX | MIN | STDEV | STDEVP | VAR | VARP | SUM }

    ( expression ) } [ ,...n ]

    [ BY expression [ ,...n ] ]

]

行聚合函数

结果

AVG

数值表达式中所有值的平均值

COUNT

选定的行数

MAX

表达式中的最高值

MIN

表达式中的最低值

STDEV

表达式中所有值的标准偏差

STDEVP

表达式中所有值的总体标准偏差

SUM

数值表达式中所有值的和

VAR

表达式中所有值的方差

VARP

表达式中所有值的总体方差

 

 

SELECT * FROM A70_USERS_ZH order by attach_id compute  min(user_id);;

 

SELECT * FROM A70_USERS_ZH order by attach_id compute  min(user_id) by attach_id;

 

3.10  SQL性能优化

3.10.1  尽量使用正逻辑而不是非逻辑,非逻辑操作(no between 、 not in 和not null)可能会降低查询速度,因为它要检索数据表中的所有行;

 

3.10.2 如果能够使用一个更确定的查询,就尽量避免使用关键字LIKE,使用LIKE查询,数据查询速度可能会降低;

 

3.10.3 只要有可能,尽量在搜索条件中使用精确的比较或值的域;

 

3.10.4使用Order by 子句可能会降低数据查询速度,

 

这篇关于第三章 SQL数据库开发--TSQL--select查询的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/775906

相关文章

mysqld_multi在Linux服务器上运行多个MySQL实例

《mysqld_multi在Linux服务器上运行多个MySQL实例》在Linux系统上使用mysqld_multi来启动和管理多个MySQL实例是一种常见的做法,这种方式允许你在同一台机器上运行多个... 目录1. 安装mysql2. 配置文件示例配置文件3. 创建数据目录4. 启动和管理实例启动所有实例

使用DeepSeek API 结合VSCode提升开发效率

《使用DeepSeekAPI结合VSCode提升开发效率》:本文主要介绍DeepSeekAPI与VisualStudioCode(VSCode)结合使用,以提升软件开发效率,具有一定的参考价值... 目录引言准备工作安装必要的 VSCode 扩展配置 DeepSeek API1. 创建 API 请求文件2.

将sqlserver数据迁移到mysql的详细步骤记录

《将sqlserver数据迁移到mysql的详细步骤记录》:本文主要介绍将SQLServer数据迁移到MySQL的步骤,包括导出数据、转换数据格式和导入数据,通过示例和工具说明,帮助大家顺利完成... 目录前言一、导出SQL Server 数据二、转换数据格式为mysql兼容格式三、导入数据到MySQL数据

MySQL分表自动化创建的实现方案

《MySQL分表自动化创建的实现方案》在数据库应用场景中,随着数据量的不断增长,单表存储数据可能会面临性能瓶颈,例如查询、插入、更新等操作的效率会逐渐降低,分表是一种有效的优化策略,它将数据分散存储在... 目录一、项目目的二、实现过程(一)mysql 事件调度器结合存储过程方式1. 开启事件调度器2. 创

SQL Server使用SELECT INTO实现表备份的代码示例

《SQLServer使用SELECTINTO实现表备份的代码示例》在数据库管理过程中,有时我们需要对表进行备份,以防数据丢失或修改错误,在SQLServer中,可以使用SELECTINT... 在数据库管理过程中,有时我们需要对表进行备份,以防数据丢失或修改错误。在 SQL Server 中,可以使用 SE

mysql外键创建不成功/失效如何处理

《mysql外键创建不成功/失效如何处理》文章介绍了在MySQL5.5.40版本中,创建带有外键约束的`stu`和`grade`表时遇到的问题,发现`grade`表的`id`字段没有随着`studen... 当前mysql版本:SELECT VERSION();结果为:5.5.40。在复习mysql外键约

SQL注入漏洞扫描之sqlmap详解

《SQL注入漏洞扫描之sqlmap详解》SQLMap是一款自动执行SQL注入的审计工具,支持多种SQL注入技术,包括布尔型盲注、时间型盲注、报错型注入、联合查询注入和堆叠查询注入... 目录what支持类型how---less-1为例1.检测网站是否存在sql注入漏洞的注入点2.列举可用数据库3.列举数据库

Oracle查询优化之高效实现仅查询前10条记录的方法与实践

《Oracle查询优化之高效实现仅查询前10条记录的方法与实践》:本文主要介绍Oracle查询优化之高效实现仅查询前10条记录的相关资料,包括使用ROWNUM、ROW_NUMBER()函数、FET... 目录1. 使用 ROWNUM 查询2. 使用 ROW_NUMBER() 函数3. 使用 FETCH FI

数据库oracle用户密码过期查询及解决方案

《数据库oracle用户密码过期查询及解决方案》:本文主要介绍如何处理ORACLE数据库用户密码过期和修改密码期限的问题,包括创建用户、赋予权限、修改密码、解锁用户和设置密码期限,文中通过代码介绍... 目录前言一、创建用户、赋予权限、修改密码、解锁用户和设置期限二、查询用户密码期限和过期后的修改1.查询用

Mysql虚拟列的使用场景

《Mysql虚拟列的使用场景》MySQL虚拟列是一种在查询时动态生成的特殊列,它不占用存储空间,可以提高查询效率和数据处理便利性,本文给大家介绍Mysql虚拟列的相关知识,感兴趣的朋友一起看看吧... 目录1. 介绍mysql虚拟列1.1 定义和作用1.2 虚拟列与普通列的区别2. MySQL虚拟列的类型2