likes
comments
collection
share

「读书笔记」MySQL查询总结

作者站长头像
站长
· 阅读数 34

前言

花了一点时间学习了MySQL相关的知识,这是一篇用来整理自己笔记的文章~~

我们所了解的数据库语句无非就是增删改查,也确实是!但是每个方向都有新的花样,你对数据库越是了解,玩的花样就越多~~ 当然这里没涉及到性能的问题,性能问题需要在不同的业务场景做取舍。

我是这么想的规范 & 规则是我在学习过程中的重点;规范是决定一条数据库语句是否成功的前提,规则是我需要去理解不同业务场景下的实现。

那接下里我们来围绕规范 & 规则展开学习~~

基础概念先知

先来看下面这张表(类比数据库表),通俗来说数据库就是一张张表的集合。红色的圈是id列;蓝色的圈是一行数据。在这基础上,需要对表进行操作,这是学习的方向。

「读书笔记」MySQL查询总结

检索数据 & 排序

  • 检索单个列 &多个列 &全部列
SELECT product_id FROM products;

SELECT product_id,product_name,product_price FROM products;

SELECT * FROM products;

规范:SELECT 列字段 FROM 数据库表名;可以根据业务查询的需要可以确定检索哪些列字段;结果是包含检索的列所对应的每行值。

  • 检索不同行
SELECT DISTINCT product_id FROM products;
SELECT DISTINCT product_id,product_name FROM products;

distinct:不同的;有区别的;关键词DISTINCT应用于所有列,而不仅仅是前置它的列;比如语句2中检索指定的这2个列都相同,否则所有行都会被检索。

规范:SELECT DISTINCT 列字段 FROM 数据库表名;DISTINCT 在业务场景下,可以用来行去重。

  • 检索限制条数
SELECT product_name FROM products LIMIT 5;
SELECT product_name FROM products LIMIT 5,5;

规范:关键词LIMIT用来限制返回的行数,可以指定开始位置;在具体的业务场景下可以用来分页。

  • 排序
SELECT product_id,product_name,product_price FROM products ORDER BY product_name;

SELECT product_id,product_name,product_price FROM products ORDER BY product_name DESC;

SELECT product_id,product_name,product_price FROM products ORDER BY product_price,product_name;

如果需要按照多个列进行排序,则在ORDER BY语句后面添加列字段即可;在逻辑上如果product_price字段都是唯一的,那么就不会按照product_name来排序。

规范:通过关键词ORDER BY子句对检索的数据进行排序(默认是升序);要保证ORDER BY子句在FROM语句之后;指定关键字 DESC来表示降序。

数据过滤

  • WHERE
SELECT product_name,product_price FROM products WHERE product_price=25;
SELECT product_name,product_price FROM products WHERE product_name='APPLE';

规范:过滤条件中将值与串类型的列进行比较需要限定引号,用来和数值列比较无需引号; 规则:SQL运行返回product_name和product_price字段,通过WHERE子句对行值过滤;

  • 操作符过滤
BETWEEN两者之间最低值和最高值:
SELECT product_name,product_price FROM products WHERE product_price BETWEEN 5 AND 10;

AND找出条件都要满足的行
SELECT product_id,product_name,product_price FROM products WHERE product_id = 1 AND product_price >= 10;

OR满足条件其一的行
SELECT product_id,product_name,product_price FROM products WHERE product_id = 1 OR product_id = 2;

SELECT product_id,product_name,product_price FROM products WHERE product_id IN (1,2) ORDER BY product_name;

NOT找出条件不匹配的行
SELECT product_id,product_name,product_price FROM products WHERE product_id NOT IN (1,2) ORDER BY product_name;

规范:使用关键字BETWEEN、AND、OR、IN、NOT IN进行数据过滤;IN关键词列举了要匹配的值清单,在功能上和OR相等;通过WHERE子句对数据进行过滤,在同时使用ORDER BYWHERE子句时,应确保ORDER BYWHERE子句之后。

  • 通配符过滤 & 正则表达式过滤
SELECT product_id,product_name,product_price FROM products WHERE product_name LINK 'jet%';

SELECT product_id,product_name,product_price FROM products WHERE product_name REGEXP '[123] ton';

规范:使用关键字LINK、REGEXP进行数据过滤;LINK和REGEXP子句需要放在WHERE子句后面; 在运行的过程中,LINK是匹配整个列,而REGEXP是在列值内匹配。

处理字段

存储在数据库表中的数据如果不是应用程序所需的格式,那么如何处理列的数据?

  • 创建计算字段
SELECT Concat(product_name,'(',product_country,')') AS product_title FROM products;

将值联结到一起构成单个值,解决方式就是拼接;通过使用Concat将列进行拼接。生成的值通过AS关键字赋予别名。

  • 利用函数来处理字段 SQL内置一些数据处理方法,可以对检索的列值进行数据处理
字段转换
SELECT product_id,Upper(product_name),product_price AS product_name_upper FROM products ORDER BY product_id;

时间过滤查询
SELECT cust_id,order_num FROM orders WHERE Date(order_date) = '2015-09-01';

求平均值
SELECT AVG(DISTINCT product_price) AS AVG_price FROM products WHERE product_id = 1;

在SQL执行的过程中,计算字段并不会自动写入数据库表中;DISTINCT只能用于数据库中已确定的列名。

分组汇总数据

GROUP BY指示SQL按vend_id排序并分组数据;执行过程中将分组的数据进行汇总
SELECT vend_id,COUNT(*) AS num_product FROM products GROUP BY vend_id;

HAVING分组过滤
SELECT cust_id,COUNT(*) AS orders FROM orders GROUP BY cust_id HAVING COUNT(*) >=2;

先分组后过滤再排序
SELECT order_num,SUM(q * item_price) AS order_total FROM ordersitems GROUP BY order_num HAVING SUM(q * item_price) >=20 ORDER BY order_total;

通过关键词GROUP BY实现分组,GROUP BY子句可以包含任意数目的列;子句中的列必须是检索的列或者说有效的表达式;HAVING支持所有WHERE操作符,但HAVING过滤指定的是分组而WHERE指定的行(先分组后过滤)

总结SELECT子句的顺序:

1、 SELECT 要返回的列或表达式; 2、FROM 从中检索数据的表; 3、WHERE 行级过滤; 4、GROUP BY 分组说明; 5、 HAVING 组级过滤; 6、ORDER BY 输出顺序排序; 7、LIMIT 要检索的函数;

组合查询

SQL可执行多个查询语句,组合查询就是取并集的结果

SELECT vend_id,prod_id,prod_price FROM products WHERE pro_price<=5 UNION SELECT vend_id,prod_id,prod_price FROM products WHERE vend_id IN (1002,1003);

对组合查询进行排序
SELECT vend_id,prod_id,prod_price FROM products WHERE pro_price<=5 UNION SELECT vend_id,prod_id,prod_price FROM products WHERE vend_id IN (1002,1003) ORDER BY vend_id,prod_price;

关键词UNION必须有2条或者2条以上的查询语句组成,每个查询语句包含相同的列、表达式或聚集函数;在使用UNION子句时,重复的行默认是取消的,如果想包含重复的行使用关键词UNION ALL可获取;在组合查询排序子句中,ORDER BY子句只能使用一条,必须出现在最后一条查询语句之后;

根据不同的业务场景使用组合查询,可以在单个查询中从不同的表返回类似结构的数据或者对单个表执行多个查询。

子查询 & 联结

子查询就是嵌套查询,SQL执行是有内到外进行查询

 SELECT prod_id,prod_name,vend_id FROM products WHERE vend_id =(SELECT vend_id FROM products WHERE prod_id ='fb');

如果在具体的业务场景下,比如某个物品存在问题,想知道生产该物品的供应商生产的其他物品;如上的SQL子查询是能实现这个场景,先找到物品的供应商,再根据供应商找其他物品。

自联结
SELECT p1.prod_id,p1.prod_name FROM products AS p1,products AS p2 WHERE p1.vend_id = p2.vend_id AND p2.prod_id = 'DTNTR';

通过自联结也能实现上述的业务场景;刚上面提到了列别名,会返回给客户机;MySQL还定义了表别名,表别名只是在查询中使用,与列别名不一样,表别名不能返回到客户机。

内部联结
SELECT customers.cust_id,orders.order_num FROM customers INNER JOIN orders ON customers.cust_id = orders.cust_id;

外部联结
SELECT customers.cust_id,orders.order_num FROM customers LEFT OUTER JOIN orders ON customers.cust_id = orders.cust_id;

两个表之间的关系是FROM子句的组成部分,以关键词INNER JOIN或者OUTER JOIN指定是内部联结还是外部联结;在使用关键词OUTER JOIN 语法时,必须有 LEFT 或者RIGHT;联结条件用ON子句而不是WHERE指定。

最后

以上是最底层SQL语句的学习,在开发过程中为了提高开发效率,我们可以借助一些Node.js ORM工具来实现SQL语句。

这里推荐Sequelizemongoose,这些工具都是对数据库的语句的二次封装,用来操作数据库~~