WITH cte_name AS ( SELECT ... ) SELECT*FROM cte_name;
如下,使用with定义了t1这一表达式,可以多次使用:
1 2 3 4 5
WITH t1 AS ( SELECT'matian'AS `name` ) SELECT tb1.`name` as n1, tb2.`name` as n2 FROM t1 as tb1, t1 as tb2
输出为:
n1
n2
matian
matian
也可使用with定义多个表达式,或者在嵌套子查询中继续使用with定义表达式,如下:
1 2 3 4 5 6 7
WITH t1 AS ( SELECT'matian'AS NAME ), t2 AS ( SELECT1AS id ) SELECT * FROM t1, t2
with CTE与视图view的区别
with仅在当次查询中有效,执行结束即释放;视图是持久存在的,是会“物化”的,会将结果集缓存活存储
with仅是构建一个表达式,视图部分情况下可以进行更新操作
因此,with只是在单个查询中用于简化语句、临时替代重复子查询,视图适合高频使用的结果集的持久化
with recursive递归查询
使用with recursive语法,相当于定义一个递归函数:
1 2 3 4 5 6 7 8
WITH RECURSIVE cte_name (column_list) AS ( SELECT initial_query_result UNION [ALL] SELECT recursive_query FROM cte_name WHERE condition ) SELECT * FROM cte_name;
WITHRECURSIVE cte ( n ) AS ( SELECT1UNIONALLSELECT n +1FROM cte WHERE n <5 ) SELECT * FROM cte;
定义了cet(n),并指定n的初始值为1,递归规则为n = n+1,递归条件为 n < 5,输出为:
1 2 3 4 5 6 7
n ----- 1 2 3 4 5
我们可以继续一个更有用的示例:实现一个字符串rightPad函数:rightpad ( str, append, n ),str为初始字符串,append为添加的字符串,n为append的重复次数。如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
WITHrecursive rightpad ( str, append, n ) AS ( SELECT cast( 'matian'ASCHAR ( 128 )) AS str, '8'AS append, 1AS n UNIONALL SELECT concat( str, append ) AS str, append AS append, n +1AS n FROM rightpad WHERE n <3 ) SELECT*FROM rightpad;
WITHrecursive inivite_relation ( iid, uid ) AS ( SELECT 0AS iid, 99AS uid UNIONALL SELECT t.invite_user_id AS iid, t.user_id AS uid FROM user_invite_tree t, inivite_relation r WHERE t.invite_user_id = r.uid ) SELECT * FROM inivite_relation;
WITHrecursive invite_relation ( iid, uid ) AS ( SELECT invite_user_id AS iid, user_id AS uid FROM user_invite_tree WHERE invite_user_id =99UNIONALL SELECT t.invite_user_id AS iid, t.user_id AS uid FROM user_invite_tree t, invite_relation r WHERE t.invite_user_id = r.uid ) SELECT * FROM invite_relation;
WITHrecursive invite_relation ( iid, uid, layer ) AS ( SELECT invite_user_id AS iid, user_id AS uid, 1AS layer FROM user_invite_tree WHERE invite_user_id =99UNIONALL SELECT t.invite_user_id AS iid, t.user_id AS uid, r.layer +1AS layer FROM user_invite_tree t, invite_relation r WHERE t.invite_user_id = r.uid AND layer <2 ) SELECT * FROM invite_relation;
WITHrecursive invite_relation ( iid, uid, layer ) AS ( SELECT invite_user_id AS iid, user_id AS uid, 1AS layer FROM user_invite_tree WHERE invite_user_id =99UNIONALL SELECT t.invite_user_id AS iid, t.user_id AS uid, r.layer +1AS layer FROM user_invite_tree t, invite_relation r WHERE t.invite_user_id = r.uid AND layer <2 ) SELECT * FROM invite_relation WHERE layer =2
WITHrecursive invite_relation_rollup ( uid, iid ) AS ( SELECT user_id AS uid, invite_user_id AS iid FROM user_invite_tree WHERE user_id =303UNIONALL SELECT user_id AS uid, invite_user_id AS iid FROM user_invite_tree t, invite_relation_rollup r WHERE t.user_id = r.iid ) SELECT * FROM invite_relation_rollup
WITHrecursive invite_relation_rollup ( uid, iid, layer ) AS ( SELECT user_id AS uid, invite_user_id AS iid, 1AS layer FROM user_invite_tree WHERE user_id =303UNIONALL SELECT user_id AS uid, invite_user_id AS iid, r.layer +1AS layer FROM user_invite_tree t, invite_relation_rollup r WHERE t.user_id = r.iid AND r.layer <2 ) SELECT * FROM invite_relation_rollup