MySQL必知必会 第7-9章

第七章 数据过滤

7.1 组合WHERE子句

在第六章介绍的所有WHERE子句在过滤时,使用的都是单一的条件。为了进行更强的过滤控制,MySQL允许给出多个WHERE子句,并通过ANDOR操作符的方式组合使用。

  • 操作符(operator)
    用来联接或改变WHERE子句中关键字,也成为逻辑操作符。
7.1.1 AND操作符

AND操作符可以使用对多列的条件进行累加过滤。

  • 输入:
    SELECT prod_id, prod_price, prod_name FROM products WHERE vend_id = 1003 AND prod_price <= 10;
  • 输出:略
  • 分析:此语句检索由供应商1003制造,且价格小于等于10美元的产品的编号、名称和价格。AND操作符“并且”的语意。
7.1.2 OR操作符

OR操作符可以使用对多列的条件进行累加过滤。

  • 输入:
    SELECT prod_id, prod_price, prod_name FROM products WHERE vend_id = 1002 OR vend_id = 1003;
  • 输出:略
  • 分析:此语句检索由供应商1002或1003制造的所有产品的编号、名称和价格。OR操作符“或者”的语意。
7.1.3 计算次序

WHERE子句可包含任意数目的ANDOR操作符。但是AND的优先级比OR高,应使用适当的圆括号分组操作符。

  • 输入:
    SELECT prod_id, prod_price, prod_name FROM products WHERE (vend_id = 1002 OR vend_id = 1003) AND prod_price >= 10;
  • 输出:略
  • 分析:此语句检索由供应商为1002,或1003,价格大于等于10美元的所有产品的编号、名称和价格。如果没有加圆括号,则 vend_id = 1003 先和 prod_price >= 10 进行AND操作,再与vend_id = 1002进行OR操作,得不到想要的结果。

注意:任何时候都不应该过分依赖默认计算次序,使用圆括号可以增加可读性,消除歧义。

7.2 IN操作符

IN操作符用来指定条件范围,范围中每个条件都可以进行匹配。IN的合法值由逗号分隔,并全部括在圆括号中。

  • 输入:
    SELECT prod_id, prod_price, prod_name FROM products WHERE vend_id IN (1002,1003);
  • 输出:略
  • 分析:此语句检索由供应商1002或1003制造的所有产品的编号、名称和价格。所完成的功能与OR类似。

使用IN的优点为:

  • 在使用长的合法选项清单时,IN操作符的语法更清楚更直观。
  • IN操作符比OR操作符清单执行更快
  • IN操作符最大的优点是可以包含其他SELECT语句(将在14章说明),能够更动态地建立WHERE子句。
7.3 NOT操作符

WHERE子句中的NOT操作符有且只有一个功能,就是否定它之后的任何条件。

  • 输入:
    SELECT prod_id, prod_price, prod_name FROM products WHERE vend_id NOT IN (1002,1003);
  • 输出:略
  • 分析:此语句检索由供应商1002或1003以外供应商提供的所有产品的编号、名称和价格。

注意:MySQL支持使用NOT对IN、BETWEEN和EXISTS子句取反,这与其他大多数DBMS允许使用NOT对各种条件取反有很大区别。

第八章 使用通配符进行过滤

8.1 LIKE操作符

之前介绍的都是针对已知值的过滤。而对进行未知内容的匹配,可以使用通配符创建比较数据的搜索模式来完成。通配符的匹配,需要通过LIKE操作符指示MySQL完成。

  • 通配符
    用来匹配值的一部分的特殊字符。

  • 搜索模式
    由字面值、通配符或两者组合成的搜索条件。

  • 谓词
    从技术上说,LIKE是谓词而不是操作符,虽然结果是相同的,但是需要明白此术语。

8.1.1 百分号(%)通配符

%表示任何字符出现任意次。例如,为了找到所有以 jet起头的产品,可使用以下SELECT语句

  • 输入:
    SELECT prod_id, prod_name FROM products WHERE prod_name LIKE 'jet%';
  • 输出:略
  • 分析:此例子使用了搜索模式 'jet%',它告诉MySQL接受jet之后任意字符,不管有多少字符。

注意:

  • %通配符可放在搜索模式的任意位置,例如 '%anvil%' 表示匹配任何位置包含anvil的字符; 's%e'表示以s开头以e结尾的字符。
  • %除了可以匹配一个或者多个字符外,还可以匹配0个字符。%代表给定位置的0、1或多个字符。
  • 尾空格将影响匹配结果:'%anvil '将匹配不到anvil_Blank
  • WHERE prod_name LIKE '%'也无法匹配NULL值作为产品名的行。
8.1.2 下划线(_)通配符

下划线(_)通配符只匹配单个字符而不是多个字符。

  • 输入:
    SELECT prod_id, prod_name FROM products WHERE prod_name LIKE '_ ton anvil';
  • 输出:略
  • 分析:此例子使用了搜索模式 '_ ton anvil',它能够匹配1 ton anvil2 ton anvil ,但不能匹配 .5 ton anvil,因为下划线通配符只对应一个字,不可多也不能少 。

通配符使用技巧:

  • 通配符的处理通常比值匹配花费的时间更多。不要过度使用通配符,能够用其他操作符达到同样目的时,应使用其他操作符。
  • 除非确实有必要,否则尽量不要在模式搜索开始时使用通配符,否则速度尤其慢。
  • 仔细注意通配符的位置,错误的位置将得不到想要的结果。

第九章 使用正则表达式进行搜索

9.1 正则表达式介绍

正则表达式是用来匹配文本的特殊串(字符集合),所有种类的程序设计语言、文本编辑器、操作系统等都支持正则表达式。

9.2 使用MySQL正则表达式

MySQL中的正则表达式仅是正则表达式的一个子集。

9.2.1 基本字符匹配
  • 输入:
    SELECT prod_name FROM products WHERE prod_name REGEXP '1000';

  • 输出:略

  • 分析:除关键词字LIKEREGEXP替代外,这条语句看上去非常像LIKE语句,但不同在于LIKE匹配整个行,REGEXP在列值中进行匹配,如果被匹配的值在文本中出现则匹配成功。因此,对于以上输入,REGEXP可以匹配到 Jet 1000,但LIKE则匹配不到。REGEXP可以通过定位符的使用,来匹配整个行,将在9.2.8中介绍定位符。

  • 输入:
    SELECT prod_name FROM products WHERE prod_name REGEXP '.000';

  • 输出:略

  • 分析:这里使用了正则表达式'.000'.是正则表达式语言中一个特殊的字符。它表示匹配任意一个字符。因此JetPack 1000·JetPack 2000都可以匹配返回。

9.2.2 进行OR匹配

为搜索两个串之一,使用(|)。

  • 输入:
    SELECT prod_name FROM products WHERE prod_name REGEXP '1000|2000' ORDER BY prod_name ;
  • 输出:略
  • 分析:这里使用了正则表达式'1000|2000'|是正则表达式语言中的OR操作符。另外,|还支持两个以上的条件,例如'1000|2000|3000'
9.2.3 匹配几个字符之一

如果想匹配特定的单一字符,可以使用[]将一组指定的内容括起来。

  • 输入:
    SELECT prod_name FROM products WHERE prod_name REGEXP '[123] ton' ORDER BY prod_name ;
    *输出:略
    分析:这里使用了正则表达式'[123] ton'[123]定义一组字符,意为匹配1、2或3。因此,1 ton2 ton3 ton都能匹配。[]是另一种形式的OR语句。

注意:

  • 事实上,'[123] ton''[1|2|3] ton'的缩写,也可以使用后者。
  • WHERE prod_name REGEXP '1|2|3 ton'并不能得到想要的答案,因为被MySQL理解为'1''2'‘3 ton’
  • 字符集也可用于否定,只需要在集合开始处放置一个^即可。例如[^123]可以匹配'1''2''3'以外的其他字符。
9.2.4 匹配范围

集合可用来定义要匹配一个或多个字符,此时可以使用-来定义一个范围,例如[0-9]表示数字0到9,[a-z]表示字母a到z。

  • 输入:
    SELECT prod_name FROM products WHERE prod_name REGEXP '[1-5] ton' ORDER BY prod_name ;
  • 输出:略
  • 分析:这里使用了正则表达式'[1-5] ton'[1-5]定义了一个范围,表示数字1到5。
9.2.5 匹配特殊字符

正则表达式语句由具有特定含义的特殊字符构成。例如|-等。如果要表示一些特殊的字母,如含.的值,则应该使用\\\为前导。\\\-表示查找-\\\.表示查找.

  • 输入:
    SELECT prod_name FROM products WHERE prod_name REGEXP '\\\.' ORDER BY prod_name ;
  • 输出:略
  • 分析:这里使用了正则表达式'\\\.',可以顺利匹配到.。这种处理方式就是所谓的转义,正则表达式内具有特殊意义的所有字符都需要转义。包括. | [ ]等,\\\\也用来引用元字符,如下:

注意:

  • 为匹配\\应使用\\\\\
  • 多数正则表达式实现单个反斜杆转义特殊字符。但MySQL要求两个反斜杆(MySQL自己解释一个,正则表达式解释一个)。
9.2.6 匹配字符类

为方便常见字符集的查找,可以使用预定义的字符集。称为字符类。如下图所示:

9.2.7 匹配多个实例

目前为止使用的所有正则表达式都试图匹配单词出现。但有时需要对匹配的数目进行更强的控制,此时可以使用下列正则表达式重复元字符来完成。

  • 输入:
    SELECT prod_name FROM products WHERE prod_name REGEXP '\\\([0-9] sticks?\\\)' ORDER BY prod_name ;

  • 输出:略
    分析:这里使用了正则表达式'\\\([0-9] sticks?\\\)'?表示,它前面的字母s出现0次或1次。

  • 输入:
    SELECT prod_name FROM products WHERE prod_name REGEXP '[[:digit:]]{4}' ORDER BY prod_name ;

  • 输出:略

  • 分析:这里使用了正则表达式'[[:digit:]]{4}',表示匹配连在一起的四位数字。

注意:使用正则表达式时,编写某个特定的表达式几乎总是有多种方法。

9.2.8 定位符

目前为止,所有例子都是匹配一个串中任意位置的文本,为了匹配特定位置的文本,需要使用定位符。

  • 输入:
    SELECT prod_name FROM products WHERE prod_name REGEXP '^[0-9\\.]' ORDER BY prod_name ;
  • 输出:略
  • 分析:^匹配串的开始,'^[0-9\\\.]' 表示匹配以数字或.开始的串。

注意:

  • ^有两个用法,在集合中(用[]定义),用来表示几何的否定,在集合外,用来表示串的起始。
  • REGEXP用来匹配子串,LIKE用来匹配整个串,REGEXP^做开头,用$为结束时,作用与LIKE相同。
  • 可在不使用数据库的情况下,对正则表达式做简单测试,REGEXP检查总是返回0或1,后者表示匹配成功。例如:SELECT 'hello' FROM ‘[0-9]';将返回0。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容