最近作数据上报的报表,发现一些基础的SQL模糊不清了,这里持续记录使用到的SQL操做。html
基本的SQL语句能够归纳为如下伪代码:sql
SELECT
DISTINCT <select_list>
FROM <left_table>
<join_type> JOIN <right_table>
ON <join_condition>
WHERE <where_condition>
GROUP BY <group_by_list>
HAVING <having_condition>
ORDER BY <order_by_condition>
LIMIT <limit_number>复制代码
搞清楚上面各个伪代码的执行顺序,对咱们写SQL有很大的帮助:shell
FROM <left_table> <join_type> JOIN <right_table> ON <join_condition>
,对两张表根据ON
操做符指定的关联条件,合并成一个临时表A。
<join_type>
包括:INNER JOIN
、Full outer join
、LEFT OUTER JOIN
、RIGHT OUTER JOIN
、CROSS JOIN
。数据库
INNER JOIN
表示合并的临时表A中,仅包含符合ON
条件的记录。LEFT OUTER JOIN
表示合并的临时表A中,不只包含符合ON
条件的记录,还会把left_table
中剩余的记录也保存在临时表,同时将对应的right_table
中的全部列字段赋值为NULL。RIGHT OUTER JOIN
表示合并的临时表A中,不只包含符合ON
条件的记录,还会把right_table
中剩余的记录也保存在临时表A,同时将对应的left_table
中的全部列字段赋值为NULL。Full outer join
表示合并的临时表A中,不只包含符合ON
条件的记录,还会把left_table
和right_table
中剩余的记录也保存在临时表A,同时将对应的另一张表的列字段赋值为NULL。其实就是两张表的交集。CROSS JOIN
表示两张表的笛卡尔积,通常不多使用。
关于JOIN
的各类使用,能够参考图解SQL的JOIN
WHERE <where_condition>
指定的过滤条件,删除一些不符合条件的记录,获得临时表B。GROUP BY <group_by_list>
指定的列字段,进行分组操做。而后根据HAVING <having_condition>
指定的条件对分组进行过滤,获得临时表C。这里HAVING指定的条件只能包含分组字段,或者其余列字段的聚合函数。SELECT DISTINCT <select_list>
规定的字段,选出仅包含指定列字段的临时表D,若是指定了DISTINCT
,那么还要把重复的行记录过滤掉。ORDER BY <order_by_condition>
指定的列字段,对临时表D的全部行记录进行排序,获得临时表E。LIMIT <limit_number>
指定的条件,从临时表E中,摘录出指定数量的行记录,生成最终的结果表。limit的用法是:limit n,m,表示从第n条记录开始选择m条记录。通常可用于列表分页,对于小数据,使用limit没有任何问题。可是当数据量很是大的时候,使用limit是很是低效的。由于limit的机制是每次都从头开始扫描,若是须要从第50万行开始,读取10条数据,那么就须要先扫描定位到第50万行,而后再读取10条记录,而扫描是一个很是低效的过程。复制代码
通常状况下,基本的SQL语句均可以按照上面6个步骤进行分析。bash
上面介绍了基本SQL语句的内部执行顺序,下面咱们看一些经常使用的SQL函数,这些函数的使用能帮助咱们解决一些复杂的SQL问题。函数
Case When Then
Case函数很像if else
语句,能够进行多条件判断。Case具备两种格式:简单Case函数和Case搜索函数。ui
CASE sex
WHEN '1' THEN '男'
WHEN '2' THEN '女'
ELSE '其余' END复制代码
CASE WHEN sex = '1' THEN '男'
WHEN sex = '2' THEN '女'
ELSE '其余' END
SELECT name, score,
(CASE WHEN score < 60 THEN '不及格'
WHEN score BETWEEN 60 AND 90 THEN '良好'
WHEN score > 90 THEN '优秀' END) as level
FROM student复制代码
上面两种方式,能够实现相同的功能。简单Case函数的写法相对比较简洁,可是和Case搜索函数相比,功能方面会有些限制,好比写判断式。spa
有以下一个数据库表,标示了各个国家的人口,要求求出亚洲和美洲的人口总数:
| country | people |
| -------- | :-----: |
| brazil | 100 |
| china | 100 |
| india | 100 |
| mexico | 100 |
| usa | 100 |
| england | 100 |code
咱们只要把属于亚洲和美洲的国家的人口累加,就能够了。因此sql语句以下所示:htm
SELECT
(case country when 'china' then "asia"
when 'india' then "asia"
when 'mexico' then "america"
when 'usa' then "america"
when 'brazil' then "america"
else
"other"
end) as continent , sum(people) as num FROM leon.TableA
group by
(case country when 'china' then "asia"
when 'india' then "asia"
when 'mexico' then "america"
when 'usa' then "america"
when 'brazil' then "america"
else
"other"
end);复制代码
上述SQL语句首先把country分为亚洲和美洲两个维度,而后根据这个新维度进行分组,并使用聚合函数,求出各个大洲的总人口。
最后得出的结果表以下所示:
| continent | num |
| -------- | :-----: |
| america | 300 |
| asia | 200 |
| other | 100 |
后续使用到继续补充...