楼主: newkid

[每日一题] 2022 PUZZLEUP

[复制链接]
论坛徽章:
548
生肖徽章2007版:猴
日期:2008-05-16 11:28:59生肖徽章2007版:马
日期:2008-10-08 17:01:01SQL大赛参与纪念
日期:2011-04-13 12:08:17授权会员
日期:2011-06-17 16:14:53ITPUB元老
日期:2011-06-21 11:47:01ITPUB官方微博粉丝徽章
日期:2011-07-01 09:45:27ITPUB十周年纪念徽章
日期:2011-09-27 16:30:472012新春纪念徽章
日期:2012-01-04 11:51:222012新春纪念徽章
日期:2020-11-30 22:13:24海蓝宝石
日期:2012-02-20 19:24:27
41#
发表于 2022-11-20 17:25 | 只看该作者
#5

SQL>
SQL>  with t(c) as (select 1 from dual union all select 2 from dual),
  2        r(n,str) as (select 3,x.c||y.c||z.c from t x,t y,t z
  3                      union all
  4                    select n + 1,
  5                           str||t.c
  6                      from r,t,lateral (select count(distinct substr(str||t.c,b,a)) uni_cnt,count(*) cnt
  7                                          from (select level b from dual connect by level <= r.n + 1) s,
  8                                               (select 3 + level - 1 a from dual connect by level <= r.n + 1 - 3) L
  9                                         where length(substr(str||t.c,b,a)) = a
10                                       ) s
11                     where n < 10
12                       and s.uni_cnt = s.cnt
13                     )
14  select length(max(to_number(str))) from r
15  /

LENGTH(MAX(TO_NUMBER(STR)))
---------------------------
                         10

使用道具 举报

回复
论坛徽章:
548
生肖徽章2007版:猴
日期:2008-05-16 11:28:59生肖徽章2007版:马
日期:2008-10-08 17:01:01SQL大赛参与纪念
日期:2011-04-13 12:08:17授权会员
日期:2011-06-17 16:14:53ITPUB元老
日期:2011-06-21 11:47:01ITPUB官方微博粉丝徽章
日期:2011-07-01 09:45:27ITPUB十周年纪念徽章
日期:2011-09-27 16:30:472012新春纪念徽章
日期:2012-01-04 11:51:222012新春纪念徽章
日期:2020-11-30 22:13:24海蓝宝石
日期:2012-02-20 19:24:27
42#
发表于 2022-11-20 17:30 | 只看该作者
这应该属于修改之前的:

SQL>
SQL>  with t(c) as (select 1 from dual union all select 2 from dual),
  2        r(n,str) as (select 3,x.c||y.c||z.c from t x,t y,t z
  3                      union all
  4                    select n + 1,
  5                           str||t.c
  6                      from r,t,lateral (select count(distinct substr(str||t.c,b,a)) uni_cnt,count(*) cnt
  7                                          from (select level b from dual connect by level <= r.n + 1) s,
  8                                               (select 3 + level - 1 a from dual connect by level <= r.n + 1 - 3) L
  9                                         where length(substr(str||t.c,b,a)) = a
10                                       ) s
11                     where n < 20
12                       and s.uni_cnt = s.cnt
13                     )
14  select max(n) from r
15  /

    MAX(N)
----------
        10

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
43#
发表于 2022-11-20 18:36 | 只看该作者
solomon_007 发表于 2022-11-20 17:30
这应该属于修改之前的: SQL> SQL>  with t(c) as (select 1 from dual union all select 2 from dual),  2 ...

lateral join,oracle真先进,duckdb刚有

使用道具 举报

回复
论坛徽章:
548
生肖徽章2007版:猴
日期:2008-05-16 11:28:59生肖徽章2007版:马
日期:2008-10-08 17:01:01SQL大赛参与纪念
日期:2011-04-13 12:08:17授权会员
日期:2011-06-17 16:14:53ITPUB元老
日期:2011-06-21 11:47:01ITPUB官方微博粉丝徽章
日期:2011-07-01 09:45:27ITPUB十周年纪念徽章
日期:2011-09-27 16:30:472012新春纪念徽章
日期:2012-01-04 11:51:222012新春纪念徽章
日期:2020-11-30 22:13:24海蓝宝石
日期:2012-02-20 19:24:27
44#
发表于 2022-11-20 21:40 | 只看该作者
〇〇 发表于 2022-11-20 18:36
lateral join,oracle真先进,duckdb刚有

Oracle 也是 12.1C 才支持。  S 子查询引用左边r,t的字段报错了,才想到这个写法。

使用道具 举报

回复
论坛徽章:
519
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
45#
 楼主| 发表于 2022-11-21 00:11 | 只看该作者
第一种翻译的写法:
with t (s,cnt)
as (
select cast(level as varchar2(40)),1 from dual connect by level<=2
union all
select t.s||n,t.cnt+1
  from t,(select level n from dual connect by level<=2)
where cnt<3
       or instr(t.s,substr(t.s,-2)||n)=0
)
select max(to_number(s)) from t;

MAX(TO_NUMBER(S))
-----------------
       2221211122

第二种,不知道何时见底,强加了个30位的限制,22秒才跑出来:

with t (s,cnt)
as (
select cast(level as varchar2(100)),1 from dual connect by level<=2
union all
select t.s||n,t.cnt+1
  from t,(select level n from dual connect by level<=2)
where cnt<3
       or not exists
          (select 1
           from dual
           where instr(substr(t.s,greatest(-level-1-level-2,-cnt)),substr(t.s,-level-1)||n)>0
           connect by level<=t.cnt-2
           )
       AND cnt<30
)         
select to_char(max(to_number(s))) from t;

TO_CHAR(MAX(TO_NUMBER(S)))
-------------------------------------
222121122211212221211222111222

使用道具 举报

回复
论坛徽章:
519
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
46#
 楼主| 发表于 2022-11-21 00:14 | 只看该作者
lateral view在12C之前也可以实现,但是要定义一个OBJECT TYPE, 然后用TABLE()写一个子查询。
我一支以为lateral view是增强的标量子查询,可以返回多行多列,后来才直到它不具备标量子查询的行间数据缓存,即使子查询的驱动条件没有变,还是会重新执行,希望未来的版本能够改善。

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
47#
发表于 2022-11-21 12:52 | 只看该作者
本帖最后由 〇〇 于 2022-11-21 12:59 编辑
newkid 发表于 2022-11-21 00:11
第一种翻译的写法:with t (s,cnt)as (select cast(level as varchar2(40)),1 from dual connect by level

30不是底,sqlite 3.40
.timer on
with recursive t1 as(select '1' n union all select '2'),
t3 as(select t1.n||t1a.n||t1b.n s from t1,t1 t1a,t1 t1b),
t as(select 1 lv, t3.s from t3
union all
select lv+1, t.s||t1.n str from t,t1 where not exists(select 1 from --t3 a,
(select value c from generate_series(1,30))c,
(select value d from generate_series(1,30))d
where --求一个字符串s所有长度>=3的子串
length(substr(s,c,d))>=3
and c<=length(s)
and c+d<=length(s)+1
--从子串的下一位开始比较
and instr(substr(t.s||t1.n,c+1),substr(s,c,d)) between 1 and length(substr(s,c,d))
)and lv<=30)
select max(length(s)) from t;
33
Run Time : real 229.472 user 229.321470 sys 0.000000


--duckdb 0.6.0
with recursive t1 as(select n from (values('1'),('2'))t(n)),
t3 as(select t1.n||t1a.n||t1b.n s from t1,t1 t1a,t1 t1b),
t as(select 1 lv, t3.s from t3
union all
select lv+1, t.s||t1.n str from t,t1 where not exists(select 1 from --t3 a,
(select c from generate_series(1,30)c(c)),
(select d from generate_series(1,30)d(d))
where --求一个字符串s所有长度>=3的子串
length(substr(s,c,d))>=3
and c<=length(s)
and c+d<=length(s)+1
--从子串的下一位开始比较
and instr(substr(t.s||t1.n,c+1),substr(s,c,d)) between 1 and length(substr(s,c,d))
)and lv<=30)
select s from t where length(s)=33;

┌───────────────────────────────────┐
│                 s                 │
│              varchar              │
├───────────────────────────────────┤
│ 221211221112221211122121122111211 │
│ 211121221112221211122121122111211 │
│ 221121221112221211122121122111211 │
│ 111212221112221211122121122111211 │
│ 211212221112221211122121122111211 │
│ 121112212112221211122121122111211 │
│ 221112212112221211122121122111211 │
│ 222112212112221211122121122111211 │
│ 121112122112221211122121122111211 │
│ 221112122112221211122121122111211 │
│                 ·                 │
│                 ·                 │
│                 ·                 │
│ 221121222111221121222121122211212 │
│ 211122121112221121222121122211212 │
│ 121122121112221121222121122211212 │
│ 221122121112221121222121122211212 │
│ 111222121112221121222121122211212 │
│ 211222121112221121222121122211212 │
│ 121222121112221121222121122211212 │
│ 221211221112221121222121122211212 │
│ 211121221112221121222121122211212 │
│ 221121221112221121222121122211212 │
├───────────────────────────────────┤
│       50568 rows (20 shown)       │
└───────────────────────────────────┘
Run Time (s): real 42.219 user 50.263522 sys 0.296402


使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
48#
发表于 2022-11-21 13:09 | 只看该作者
newkid 发表于 2022-11-21 00:11
第一种翻译的写法:with t (s,cnt)as (select cast(level as varchar2(40)),1 from dual connect by level

把你的改写成duckdb语法
with recursive t (s,cnt)
as (
select * from (values('1',1),('2',2))
union all
select t.s||n,t.cnt+1
  from t,(select n from (values(1),(2))t(n))
where cnt<3
       or not exists
          (select 1
           from generate_series(1,100)x(level)
           where level<=t.cnt-2 and instr(substr(t.s,greatest(-level-1-level-2,-cnt)),substr(t.s,-level-1)||n)>0
           )
       AND cnt<30
)
select max(s::hugeint)::varchar from t;
┌──────────────────────────────────────────┐
│ CAST(max(CAST(s AS HUGEINT)) AS VARCHAR) │
│                 varchar                  │
├──────────────────────────────────────────┤
│ 122212112221121222121122211122           │
└──────────────────────────────────────────┘
Run Time (s): real 2.308 user 3.354021 sys 0.000000

使用道具 举报

回复
论坛徽章:
548
生肖徽章2007版:猴
日期:2008-05-16 11:28:59生肖徽章2007版:马
日期:2008-10-08 17:01:01SQL大赛参与纪念
日期:2011-04-13 12:08:17授权会员
日期:2011-06-17 16:14:53ITPUB元老
日期:2011-06-21 11:47:01ITPUB官方微博粉丝徽章
日期:2011-07-01 09:45:27ITPUB十周年纪念徽章
日期:2011-09-27 16:30:472012新春纪念徽章
日期:2012-01-04 11:51:222012新春纪念徽章
日期:2020-11-30 22:13:24海蓝宝石
日期:2012-02-20 19:24:27
49#
发表于 2022-11-21 13:56 | 只看该作者
〇〇 发表于 2022-11-17 09:36
连续4个的序列重复必然导致连续3个的序列重复,只要保证3个就行了?

对啊,先还没注意到你这个句话,看了你们的才知道,你们只判断了3位,我是老老实实把整个字符串分解出所有可能,除了自身。

使用道具 举报

回复
论坛徽章:
519
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
50#
 楼主| 发表于 2022-11-22 00:20 | 只看该作者
〇〇 发表于 2022-11-21 13:09
把你的改写成duckdb语法with recursive t (s,cnt)as (select * from (values('1',1),('2',2))union allsele ...

才两秒多,鸭子这么猛?最多能算到几位?

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表