目录
若字段为null,设置值
mysql
-- 使用 IFNULL 函数
SELECT IFNULL(column_name, replacement_value) FROM table_name;
达梦
-- 使用 NVL 函数
SELECT NVL(column_name, replacement_value) FROM table_name;
使用场景举例
查询一个字段,我需要用它进行统计,如果里面有null值,需要将其设置为 0
查找值是否在字符串里面
mysql
-- 使用 FIND_IN_SET 函数
SELECT column_name FROM table_name WHERE FIND_IN_SET(search_value, column_name) > 0;
达梦
-- 使用 LOCATE 函数
SELECT column_name FROM table_name WHERE LOCATE(search_value, column_name) > 0;
使用场景举例
比如,若依管理系统里面,我想找到部门ID为100的所有层级子部门。
思路:
有父ID(parent_id),我们可以查到二级子部门(dept_id为 101,102),然后再找父ID为 101,102 的部门,如此下去麻烦。
ancestors:当前部门的组级部门
// 下面 100 可以根据实际情况调整
SELECT dept_id
FROM sys_dept
WHERE dept_id <> 100
AND FIND_IN_SET(100,ancestors)
扩展
公司如果没有记录这个组级路径怎么办?
SELECT t.dept_id
FROM sys_dept AS t
JOIN (
SELECT dept_id, @parent_id := 100 AS parent_id
FROM sys_dept
WHERE dept_id = 100
UNION ALL
SELECT t1.dept_id, t1.parent_id
FROM sys_dept AS t1
JOIN (SELECT @parent_id := 100) AS t2
WHERE t1.parent_id = @parent_id
) AS sub ON t.parent_id = sub.dept_id;
使用了一个自连接和一个变量 @parent_id 来实现递归查询。
首先,我们从 sys_dept 表中选择 dept_id 为 100 的记录,并将其作为初始节点。
然后,通过递归地将每个节点与其父节点进行连接,我们可以找到所有的子节点。
最后,查询返回所有子节点的 dept_id。
分组后串拼接
mysql
-- 使用 GROUP_CONCAT 函数
SELECT GROUP_CONCAT(column_name SEPARATOR ',') FROM table_name;
达梦
-- 使用 WM_CONCAT 函数
SELECT WM_CONCAT(column_name) FROM table_name;
使用场景举例
这个经常使用到,工作中, left join 连接,一对多的情况下,你希望知道主表一条记录对应从表的某个字段有哪些值。
SELECT category, GROUP_CONCAT(product_name SEPARATOR ',') AS products
FROM products
GROUP BY category;
拓展
使用 wm_concat 默认为 逗号 分割,如果我想按分号分割怎么办?
-- 使用 WM_CONCAT 函数
SELECT replace(WM_CONCAT(column_name),',',';') FROM table_name;
注意
达梦数据库中还有个listagg,但是公司规范中有说明:
达梦数据库SQL语句字符串拼接时、行列转换时要求使用wm_concat,而非listagg、listagg2,因为达梦中listagg、listagg2性能很低。