SQLTips
-
表连接问题
1.1 表连接方式JOIN:
inner join 默认连接方式,只返回两表交集数据
full join 笛卡尔连接方式,返回两个集合所有连接方式产生的数据
在查询时直接用where也相当于是全连接方式
★在写查询语句时尽量用连接代替where条件。
left join 以左表为主表,返回左表所有以及来自右表的补充数据
right join 右连接,类似于左连接,但以右表为主表
1.2 ★表连接之后会生成一张连接后的临时表,所以若表连接后字段名不冲突,可以不对表进行重命名,代码运行稍快一点点。 -
查询表中指定排序的数据
2.1 LIMIT X, Y :跳过X个数据,读取Y个数据。
OFFSET:跳过X个数据。
LIMIT X OFFSET Y:跳过X个数据,读取Y个数据。
2.2 ★要查询的数据不存在时返回Null而不是空
SELECT IFNULL(查询条件,NULL)
-
查询重复问题——>转化为计数问题
GROUP BY 待查字段 HAVING COUNT(待查字段) > 1
4.在写查询条件时要注意灵活处理,只要能达到相同的取数效果就可以,不一定非要直译条件。
如:不存在于某个子查询条件中——>计数为0——>表连接后某字段数据为空/Null
删除某个字段重复的数据并保留Id最小的——>相同的,Id大的删掉。
5. 日期函数
DATEDIFF() 函数返回两个日期之间的时间。
语法
DATEDIFF(datepart,startdate,enddate)
startdate 和 enddate 参数是合法的日期表达式。
datepart 参数可以是下列的值:
年 yy, yyyy;
季度 qq, q;
月 mm, m;
年中的日 dy, y;
日 dd, d;
周 wk, ww;
星期 dw, w;
小时 hh;
分钟 mi, n;
秒 ss, s;
毫秒 ms;
微妙 mcs;
纳秒 ns
6.两个取数条件中只需满足任意一个时
6.1 LI 用OR连接两个条件或
6.2 用UNION连接两个子查询(运行稍快一些)
UNION 操作符用于合并两个或多个 SELECT 语句的结果集。
★UNION 内部的每个 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每个 SELECT 语句中的列的顺序必须相同。
SQL UNION 语法
SELECT column_name(s) FROM table1 UNION SELECT column_name(s) FROM table2;
注释:默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。
SQL UNION ALL 语法
SELECT column_name(s) FROM table1 UNION ALL SELECT column_name(s) FROM table2;
注释:UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。
7.统计:
group by 字段名 having count(distinct 字段名);
8.奇书,偶数
mod(id,2) = 1
mod(id,2) = 0
9.replace
replace(str, str_from , str_to)
灵活用法:用于在字段只有两个特征值时的互相交换
例如:将数据的性别交换
sex = replace("fm", sex, "")
10.行转列问题
10.1例如:工资表中有月份字段,要将该字段行转为列字段
SELECT id,
SUM(CASE WHEN month='Jan' THEN revenue END) AS Jan_Revenue,
SUM(CASE WHEN month='Feb' THEN revenue END) AS Feb_Revenue,
FROM department
GROUP BY id
ORDER BY id;
10.2 group by起的作用
GROUP BY id 会使department表按照id分组,生成一张虚拟表(假想中的表)如下:
+------+---------+-------+
| id | revenue | month |
+------+---------+-------+
| | 8000 | Jan |
| 1 | 7000 | Feb |
| | 6000 | Mar |
+------+---------+-------+
| 2 | 9000 | Jan |
+------+---------+-------+
| 3 | 10000 | Feb |
在虚拟表中,所有id=1的revenue或者month数据都写在了同一个单元格中,如8000、7000、6000都是写在同一单元格内的。真正的表是不能这样写的,所以这种写法只存在于虚拟表中,帮助我们理解。
10.3 case when的原理
当一个单元格中有多个数据时,case when只会提取当中的第一个数据。
以CASE WHEN month=‘Feb’ THEN revenue END 为例,当id=1时,它只会提取month对应单元格里的第一个数据,即Jan,它不等于Feb,所以找不到Feb对应的revenue,所以返回NULL。(可以试试把我上面答案里的sum()统统去掉,执行结果与预期不一样。错就错在当id=1时,Feb_Revenue和Mar_Revenue的值变成了NULL)
那该如何解决单元格内含多个数据的情况呢?答案就是使用聚合函数,聚合函数就用来输入多个数据,输出一个数据的。如SUM()或MAX(),而每个聚合函数的输入就是每一个多数据的单元格。
以SUM(CASE WHEN month=‘Feb’ THEN revenue END) 为例,当id=1时,它提取的Jan、Feb、Mar,从中找到了符合条件的Feb,并最终返回对应的revenue的值,即7000。