zoukankan      html  css  js  c++  java
  • mysql 必知必会整理—sql 排序与过滤[三]

    前言

    简单整理一下MySQL的排序与过滤。

    正文

    我们查询出来的结果有时候是希望进行排序的,比如说:

    select product_name
    from products
    order by prod_name
    

    经常需要按不止一个列进行数据排序。例如,如果要显示雇员清单,可能希望按姓和名排序(首先按姓排序,然后在每个姓中再按名排序)。如果多个雇员具有相同的姓,这样做很有用。

    这里面就是先按照prod_price,如果prod_price 相同的话,那么按照prod_name来。

    数据排序不限于升序排序(从A到Z)。这只是默认的排序顺序,还可以使用ORDER BY子句以降序(从Z到A)顺序排序。为了进行降序排序,必须指定DESC关键字。

    注意:

    在多个列上降序排序 如果想在多个列上进行降序排序,必须
    对每个列指定DESC关键字。
    
    区分大小写和排序顺序 在对文本性的数据进行排序时,A与 a相同吗?a位于B之前还是位于Z之后?这些问题不是理论问
    题,其答案取决于数据库如何设置。
    在字典(dictionary)排序顺序中,A被视为与a相同,这是MySQL
    (和大多数数据库管理系统)的默认行为。但是,许多数据库
    管理员能够在需要时改变这种行为(如果你的数据库包含大量
    外语字符,可能必须这样做)。
    这里,关键的问题是,如果确实需要改变这种排序顺序,用简
    单的ORDER BY子句做不到。你必须请求数据库管理员的帮助。
    

    过滤语句,一般指的是where 子句。

    数据库表一般包含大量的数据,很少需要检索表中所有行。通常只
    会根据特定操作或报告的需要提取表数据的子集。只检索所需数据需要
    指定搜索条件(search criteria),搜索条件也称为过滤条件(filter 
    condition)。
    

    一般使用where 来进行过滤。

    比如说:

    select *
    from product
    where price>100
    

    表示过滤出100的价格。

    SQL过滤与应用过滤 数据也可以在应用层过滤。为此目
    的,SQL的SELECT语句为客户机应用检索出超过实际所需的
    数据,然后客户机代码对返回数据进行循环,以提取出需要
    的行。
    通常,这种实现并不令人满意。因此,对数据库进行了优化,
    以便快速有效地对数据进行过滤。让客户机应用(或开发语言)
    处理数据库的工作将会极大地影响应用的性能,并且使所创建
    的应用完全不具备可伸缩性。此外,如果在客户机上过滤数据,
    服务器不得不通过网络发送多余的数据,这将导致网络带宽的
    浪费。
    

    where 子句通常有操作符。

    这里需要注意的是一个null值,NULL 无值(no value),它与字段包含0、空字符串或仅仅包含
    空格不同。

    可以看到这里显示的是is,而不是==,至于为什么可以查看我的整理1800篇sql语句中查看。

    NULL与不匹配 在通过过滤选择出不具有特定值的行时,你
    可能希望返回具有NULL值的行。但是,不行。因为未知具有
    特殊的含义,数据库不知道它们是否匹配,所以在匹配过滤
    或不匹配过滤时不返回它们。 
    因此,在过滤数据时,一定要验证返回数据中确实给出了被
    过滤列具有NULL的行。
    

    在使用where的时候,我们一般要知道另外交给关键词,and or in not 这几个操作符号。

    and 例子:

    OR操作符与AND操作符不同,它指示MySQL检索匹配任一条件的行。

    or 例子:

    WHERE可包含任意数目的AND和OR操作符。允许两者结合以进行复杂和高级的过滤。

    但是,组合AND和OR带来了一个有趣的问题。

    先说一下其本来的意思,其查询条件为vend_id=1002或者vend_id 为1003的,且价格要大于10元的。

    但是按照上面的指示,

    SQL(像多数语言一样)在处理OR操作符前,优先处理AND操
    作符。当SQL看到上述WHERE子句时,它理解为由供应商1003制造的任何
    价格为10美元(含)以上的产品,或者由供应商1002制造的任何产品,
    而不管其价格如何。换句话说,由于AND在计算次序中优先级更高,操作
    符被错误地组合了。

    此问题的解决方法是使用圆括号明确地分组相应的操作符。请看下
    面的SELECT语句及输出:

    在WHERE子句中使用圆括号 任何时候使用具有AND和OR操作
    符的WHERE子句,都应该使用圆括号明确地分组操作符。不要
    过分依赖默认计算次序,即使它确实是你想要的东西也是如
    此。使用圆括号没有什么坏处,它能消除歧义。
    

    下面介绍一下in 操作符:

    圆括号在WHERE子句中还有另外一种用法。IN操作符用来指定条件范
    围,范围中的每个条件都可以进行匹配。IN取合法值的由逗号分隔的清
    单,全都括在圆括号中。下面的例子说明了这个操作符:
    

    此SELECT语句检索供应商1002和1003制造的所有产品。IN操作符后跟由逗号分隔的合法值清单,整个清单必须括在圆括号中

    in 和 or 有相同的效果,那么有时候为什么要使用in呢?

     在使用长的合法选项清单时,IN操作符的语法更清楚且更直观。

     在使用IN时,计算的次序更容易管理(因为使用的操作符更少)。

     IN操作符一般比OR操作符清单执行更快。

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

    这里的NOT否定跟在它之后的条件,因此,MySQL不是匹配1002
    和 1003 的 vend_id ,而是匹配 1002 和 1003 之外供应商的
    vend_id。

    这里再介绍两个东西,一个是exits和 not exits。

    exit 其实用的不多,因为其替代性强。

    比如:

    要求:查询选修了课程”操作系统“的同学

    select sname from student
    
    where exits (select * from sc,course where sno = student.sno and sc.cno = course.cno and course.cname ="操作系统")
    

    完全可以这样替代:

    select * from sc,course,student where sc.sno = student.sno and sc.cno = course.cno and course.cname ="操作系统"
    

    但是如果是现在需求是这样的:

    查询没有选修课程”操作系统“的同学

    select sname from student
    
    where not exits (select * from sc,course where sno = student.sno and sc.cno = course.cno and course.cname ="操作系统")
    

    这样似乎有点艰难吧,可能有些初学者认为这样:

    select * from sc,course,student where sc.sno = student.sno and sc.cno = course.cno and course.cname !="操作系统"
    

    这当然是不对的啦,因为是先做笛卡儿积,然后再做where过滤,这样当然是不满足条件的了。

  • 相关阅读:
    最小生成树(Prim和Kruscal)
    SPFA(还是稍微写写吧,虽然没什么用)
    最短路径(随便写写)(Floyd,Bellman-Ford,Dijkstra)
    Just a Hook HDU
    数论逆元
    最长上升子序列(LIS)算法(附Codeforces Round #641 (Div. 2),B题题解)
    Educational Codeforces Round 86 (Rated for Div. 2)
    Codeforces Round #633 (Div. 2)
    Codeforces Round #631 (Div. 2)
    Mayor's posters(线段树离散化)
  • 原文地址:https://www.cnblogs.com/aoximin/p/15314284.html
Copyright © 2011-2022 走看看