SQL必知必会学习笔记(一)

数据库基础

数据库数据库软件
确切的说,数据库软件应称为数据库管理系统(DBMS),数据库是通过DBMS创建和操作的容器

数据库相当于文件柜(容器),表相当于文件

同一个数据库不能存在相同的表名,不同的数据库可以存在相同的表名

主键应满足的条件:

  • 唯一性
  • 非空性(NOT NULL)
  • 主键列中的值不允许修改或更新
  • 主键值不能重用(某行从表中删除,其主键不能赋给新行)
    注:可以一起使用多个列作为主键,所有列值的组合必须是唯一的,但其中单个列的值可以不唯一

检索数据

SQL语句一般返回原始的、无格式的数据,不同的DBMS和客户端显示数据的方式略有不同,数据的格式化是表示问题,而不是检索问题

select * from products; 一般而言,除非确实需要表中的每一列,否则最好别使用*通配符,检索不需要的列通常会降低检索速度和应用程序的性能;当然,通配符也有一个大优点:可以检索出名字未知的列

select distinct vend_id, prod_price from products; 使用distinct检索不同的列值,注意distinct关键字作用于其后所有的列,不仅仅是跟在其后的一列,即取多个列组合起来不同结果

当需要返回一定数量的行时,各种数据库的实现并不相同:

  • SQL Server:select top 5 prod_name from products;
  • DB2:select prod_name from products fetch first 5 rows only;
  • Oracle:select prod_name from products where rownum <=5;
  • MySQL、SQLite等:select prod_name from products limit 5;

当需要从指定位置开始检索一定数量的行数时,limitoffset组合使用
select prod_name from products limit 4 offset 3; 从第4行开始,检索4行数据(起始行为第0行);MySQL、MariaDB、SQLite中可以把limit 4 offset 3 简化为limit 3,4 ,注意 , 之前的值对应offset,, 之后的值对应limit(反过来了)

使用注释

  • 行内注释
    --文本,可以嵌在行内,--之后的文本就是注释
    #文本,在一行的开始处使用#,这一整行都将作为注释
select prod_name from products;      --这是一条注释
#这是一条注释
select prod_name from products;       
  • 多行注释
    /*文本*/,从 /**/ 之间的所有内容都是注释
/*select prod_name ,
vend_id 
from products; */
select prod_name from products;

排序检索

SQL语句由子句构成,有些子句是必需的,有些则是可选的。一个子句通常由一个关键字加上所提供的数据组成。例如select语句的from子句。

order by 子句:取一个或多个列的名字,据此对输出进行排序。
注意:在指定一条 order by 子句时,应该保证它是select语句中最后一条子句。如果它不是最后的子句,将会出错。

按列位置(相对位置)排序:

除了能用列名指出排序顺序外,order by 还支持按相对位置进行排序。

select prod_id, prod_price, prod_name
from Products
order by 2, 3;

order by 2 表示按select清单中的第二个列prod_price进行排序;order by 2, 3 表示先按prod_price,再按prod_name进行排序。
这一技术的主要好处在于不用重新输入列名;缺点是可能造成错用列名、对select清单进行更改时容易错误地对数据进行排序、如果进行排序的列不在select清单中,显然不能使用这项技术。
如果有必要,可以混合使用实际列名和相对列位置

指定排序方向

数据排序默认是升序排序(从A到Z),当然,也可以使用DESC关键字在order by 子句中进行降序排序

select prod_id, prod_price, prod_name
from Products
order by prod_price DESC, prod_name;

DESC关键字只应用到直接位于其前面的列名,因此,上面的语句prod_price列以降序排序,而prod_name列(在每个价格内)仍然以默认升序排序

注意:如果想在多个列上进行降序排列,必须对每一列指定DESC关键字

过滤数据

SQL过滤与应用过滤
SQL过滤之后,数据也可以在应用层过滤,但是通常这种做法及其不妥。优化数据库后可以更快速有效地对数据进行过滤。而让客户端应用(或开发语言)处理数据库的工作将会极大地影响应用的性能,并且使所创建的应用完全不具备可伸缩性。此外,如果在客户端过滤数据,服务器不得不通过网络发送多余的数据,这将导致网络带宽的浪费。

使用between关键字时,必须指定两个值--所需范围的低端值和高端值,这两个值必须用and关键字分隔。between匹配范围中的所有的值,包括指定的开始值和结束值,即左闭右闭[ ]区间。

确定值是否为NULL,不能简单地检查是否等于NULL,select语句有一个特殊的where子句,可用来检查具有NULL值的列,这个where子句就是 IS NULL 子句

select cust_name
from Customers
where cust_email IS NULL;

NULL和非匹配
通过过滤选择不包含指定值的所有列时,我们可能希望返回包含NULL值的行,但是这做不到,因为NULL比较特殊,所以在进行匹配过滤或非匹配过滤时,不会返回这些结果。

高级数据过滤

where子句中使用圆括号

任何时候使用具有AND和OR操作符的where子句,都应该使用圆括号明确地分组操作符。不要过分依赖默认求值顺序,即使它确实如你希望的那样。使用圆括号没有什么坏处,它能消除歧义。

IN操作符

where子句中用来指定要匹配的清单的关键字,功能与OR相当
其优点如下:

  • 在有很多合法选项时,IN操作符的语法更清楚、更直观
  • 在与其他AND和OR操作符组合使用IN时,求值顺序更容易管理
  • IN操作符一般比一组OR操作符执行得更快
  • IN操作符的最大优点是可以包含其他select语句,能够动态地建立where子句
NOT操作符

where子句中用来否定其后条件的关键字

select prod_name
from Products
where NOT vend_id = 'DLL01'
order by prod_name;

上面的例子也可以使用 <> 操作符来完成

select prod_name
from Products
where vend_id <> 'DLL01'
order by prod_name;

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

用通配符进行过滤

通配符本身实际上是SQL的where子句中有特殊含义的字符,SQL支持几种通配符。为在搜索子句中使用通配符必须使用LIKE操作符。LIKE指示DBMS,后跟的搜索模式利用通配符匹配而不是简单的相等匹配进行比较。

最常使用的通配符是百分号(%),表示任何字符出现任意次数(0次、1次或多次)。

select prod_id, prod_name
from Products
where prod_name like 'Fish%';

此例子使用了搜索模式 'Fish%' ,将检索任意以Fish起头的词,%告诉DBMS接受Fish之后的任意字符,不管它有多少字符
MySQL等DBMS默认搜索是不区分大小写的,根据DBMS的不同及其配置,搜索是可以区分大小写的。如果区分大小写,则 'fish%' 与 Fish bean bag toy就不匹配

注意NULL:通配符%看起来像是可以匹配任何东西,但有个例外,这就是NULL。子句 where prod_name like '%' 不会匹配产品名称为NULL的行

另一个有用的通配符是下划线(_),它只匹配单个字符,而不是多个字符。

select prod_id, prod_name
from Products
where prod_name like '__ inch teddy bear';

注意这个where子句中的搜索模式给出了后面跟有文本的两个通配符,结果如下:
图6-1

8 inch teddy bear 产品没有匹配,因为搜索模式要求匹配两个通配符而不是一个,%通配符则可以有任意多个。

% 能匹配任意个数的字符不同,_ 总是刚好匹配一个字符,不能多也不能少。

使用通配符的技巧:

正如所见,SQL的通配符很有用,但这种功能是有代价的,即通配符搜索一般比前面讨论的其他搜索要耗费更长的处理时间,这里给出一些使用通配符时要记住的技巧:

  • 不要过度使用通配符。如果其他操作符能达到相同的目的,应该使用其他操作符
  • 在确实需要使用通配符时,也尽量不要把它们用在搜索模式的开始处。把通配符置于开始处,搜索起来是最慢的
  • 仔细注意通配符的位置。如果放错地方,可能不会返回想要的数据
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,386评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,142评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,704评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,702评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,716评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,573评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,314评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,230评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,680评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,873评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,991评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,706评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,329评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,910评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,038评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,158评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,941评论 2 355

推荐阅读更多精彩内容