|
|
本帖最后由 〇〇 于 2021-10-20 08:36 编辑
改为mysql8的语法,cast有问题
with RECURSIVE t6(n) as (select 1 union all select n+1 from t6 where n<6)
,
b3(a,b,c,bit)as(select a.n,b.n,c.n,(1<<(a.n-1))+(1<<(b.n-1))+(1<<(c.n-1)) from t6 a,t6 b,t6 c where a.n<b.n and b.n<c.n)
,
b9(b)as(select c.bit*((1<<(r.a-1)*6)+(1<<(r.b-1)*6)+(1<<(r.c-1)*6)) from b3 c,b3 r)
,
t(n,c,x,y)
as(select 1,cast('1' as char(100)),1,1 union all select n+1,cast(n+1 as char(100)),n/6+1,n%6+1 from t where n<6*6)
,
s(lv,n,nlist,blist,px,py)
as(select 1,t.n,t.c,1<<(t.n-1),pow(10,t.x),pow(10,t.y) from t where t.n<=6
union all
select lv+1,b.n,trim(nlist)||','||trim(c),blist+(1<<(b.n-1)),px+pow(10,b.x),py+pow(10,b.y)
from s,t b
where lv<10 and s.n<b.n
and(blist%19<14)
and (instr(px+pow(10,b.x),3)=0 and instr(py+pow(10,b.y),3)=0)
and b.n between lv/2*6+1 and lv/2*6+6*2
)
select * from s where lv=10 and (lv<3 or not exists(select 1 from b9 where (blist & b9.b) =0))
limit 10;
+------+------+-------+------------+---------+---------+
| lv | n | nlist | blist | px | py |
+------+------+-------+------------+---------+---------+
| 10 | 31 | 1 | 1344948364 | 2122210 | 2122210 |
| 10 | 31 | 1 | 1381024416 | 2222200 | 1222210 |
| 10 | 31 | 1 | 1377970452 | 2212210 | 2212210 |
| 10 | 31 | 1 | 1378485012 | 2221210 | 1222210 |
| 10 | 31 | 1 | 1378403616 | 2222200 | 1222210 |
| 10 | 31 | 1 | 1414047756 | 2222110 | 1222210 |
| 10 | 31 | 1 | 1414055946 | 2222110 | 1222210 |
| 10 | 31 | 1 | 1411982112 | 2222200 | 1222210 |
| 10 | 31 | 1 | 125**8892 | 2221210 | 2122210 |
| 10 | 31 | 1 | 1246364940 | 2221210 | 1222210 |
+------+------+-------+------------+---------+---------+
10 rows in set, 2 warnings (8.55 sec)
mysql> show warnings
-> ;
+---------+------+-------------------------------------------------------------------------------------------------------+
| Level | Code | Message |
+---------+------+-------------------------------------------------------------------------------------------------------+
| Warning | 1287 | '|| as a synonym for OR' is deprecated and will be removed in a future release. Please use OR instead |
| Warning | 1287 | '|| as a synonym for OR' is deprecated and will be removed in a future release. Please use OR instead |
+---------+------+-------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)把||操作符改为concat()函数可以了
with RECURSIVE t6(n) as (select 1 union all select n+1 from t6 where n<6)
,
b3(a,b,c,bit)as(select a.n,b.n,c.n,(1<<(a.n-1))+(1<<(b.n-1))+(1<<(c.n-1)) from t6 a,t6 b,t6 c where a.n<b.n and b.n<c.n)
,
b9(b)as(select c.bit*((1<<(r.a-1)*6)+(1<<(r.b-1)*6)+(1<<(r.c-1)*6)) from b3 c,b3 r)
,
t(n,c,x,y)
as(select 1,cast('1' as char(100)),1,1 union all select n+1,cast(n+1 as char(100)),n/6+1,n%6+1 from t where n<6*6)
,
s(lv,n,nlist,blist,px,py)
as(select 1,t.n,t.c,1<<(t.n-1),pow(10,t.x),pow(10,t.y) from t where t.n<=6
union all
select lv+1,b.n,concat(trim(nlist),',',trim(c)),blist+(1<<(b.n-1)),px+pow(10,b.x),py+pow(10,b.y)
from s,t b
where lv<10 and s.n<b.n
and(blist%19<14)
and (instr(px+pow(10,b.x),3)=0 and instr(py+pow(10,b.y),3)=0)
and b.n between lv/2*6+1 and lv/2*6+6*2
)
select * from s where lv=10 and (lv<3 or not exists(select 1 from b9 where (blist & b9.b) =0))
limit 10;
+------+------+-----------------------------+------------+---------+---------+
| lv | n | nlist | blist | px | py |
+------+------+-----------------------------+------------+---------+---------+
| 10 | 31 | 6,8,10,15,16,21,23,26,29,31 | 1381024416 | 2222200 | 1222210 |
| 10 | 31 | 3,5,9,12,14,18,22,26,29,31 | 1377970452 | 2212210 | 2212210 |
| 10 | 31 | 3,5,9,10,18,20,22,26,29,31 | 1378485012 | 2221210 | 1222210 |
| 10 | 31 | 6,9,11,15,16,20,22,26,29,31 | 1378403616 | 2222200 | 1222210 |
| 10 | 31 | 3,4,12,14,16,20,23,27,29,31 | 1414047756 | 2222110 | 1222210 |
| 10 | 31 | 2,4,12,15,16,20,23,27,29,31 | 1414055946 | 2222110 | 1222210 |
| 10 | 31 | 3,4,8,12,17,21,24,26,28,31 | 125**8892 | 2221210 | 2122210 |
| 10 | 31 | 3,4,9,11,18,20,23,26,28,31 | 1246364940 | 2221210 | 1222210 |
| 10 | 31 | 6,8,11,15,16,21,23,26,28,31 | 1246807200 | 2222200 | 1222210 |
| 10 | 31 | 2,4,11,14,18,21,24,27,28,31 | 1284645898 | 2222110 | 2122210 |
+------+------+-----------------------------+------------+---------+---------+
10 rows in set (7.55 sec)
cast as char实际上达到了varchar的效果
mysql> select concat(cast(1 as char),cast(32 as char));
+------------------------------------------+
| concat(cast(1 as char),cast(32 as char)) |
+------------------------------------------+
| 132 |
+------------------------------------------+
1 row in set (0.00 sec)
mysql> select concat(cast(1 as char(10)),cast(32 as char));
+----------------------------------------------+
| concat(cast(1 as char(10)),cast(32 as char)) |
+----------------------------------------------+
| 132 |
+----------------------------------------------+
除法也需要改为floor,和oracle差不多,也能检测出第一个t6写成t的错误,速度和postgresql差不多
mysql> with RECURSIVE t6(n) as (select 1 union all select n+1 from t6 where n<6)
-> ,
-> b3(a,b,c,bit)as(select a.n,b.n,c.n,(1<<(a.n-1))+(1<<(b.n-1))+(1<<(c.n-1)) from t6 a,t6 b,t6 c where a.n<b.n and b.n<c.n)
-> ,
-> b9(b)as(select c.bit*((1<<(r.a-1)*6)+(1<<(r.b-1)*6)+(1<<(r.c-1)*6)) from b3 c,b3 r)
-> ,
-> t(n,c,x,y)
-> as(select 1,cast('1' as char(100)),1,1 union all select n+1,cast(n+1 as char(100)),floor(n/6)+1,n%6+1 from t where n<6*6)
-> ,
-> s(lv,n,nlist,blist,px,py)
-> as(select 1,t.n,t.c,1<<(t.n-1),pow(10,t.x),pow(10,t.y) from t where t.n<=6
-> union all
-> select lv+1,b.n,concat(nlist,',',c),blist+(1<<(b.n-1)),px+pow(10,b.x),py+pow(10,b.y)
-> from s,t b
-> where lv<10 and s.n<b.n
-> and (instr(px+pow(10,b.x),3)=0 and instr(py+pow(10,b.y),3)=0)
-> and b.n between floor(lv/2)*6+1 and floor(lv/2)*6+6*2
-> )
-> select count(*) from s where lv=10 and not exists(select 1 from b9 where (blist & b9.b) =0)
-> ;
+----------+
| count(*) |
+----------+
| 32400 |
+----------+
1 row in set (2 min 59.69 sec)
|
|