查看: 1380|回复: 5

[每日一题] PL/SQL Challenge 每日一题:2019-1-24 LIKE条件

[复制链接]
论坛徽章:
520
奥运会纪念徽章:垒球
日期: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
跳转到指定楼层
1#
发表于 2019-1-29 04:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

最先答对且答案未经编辑的puber将获得纪念章一枚(答案不可编辑但可发新贴补充或纠正),其他会员如果提供有价值的分析、讨论也可获得纪念章一枚。

每两周的优胜者可获得itpub奖励的技术图书一本。

以往旧题索引:
http://www.itpub.net/forum.php?m ... eid&typeid=1808

原始出处:
http://www.plsqlchallenge.com/

作者: Kim Berg Hansen

运行环境:SQLPLUS, SERVEROUTPUT已打开
注:本题给出答案时候要求给予简要说明才能得到奖品

我有一张表保存着课程信息:

create table qz_courses (
   id       integer primary key
, code     varchar2(10) not null
, name     varchar2(30)
)
/

create unique index qz_courses_code_ix on qz_courses (code)
/

insert into qz_courses values (40, 'PLSQL01', 'Control statements')
/
insert into qz_courses values (41, 'PLSQL04', 'Collection methods')
/
insert into qz_courses values (42, 'SQL10'  , 'RANGE versus ROWS')
/
insert into qz_courses values (43, 'SQL16'  , 'Linear regression')
/
commit
/

我想要一个有关SQL的课程的列表,按照我的定义,只要是CODE这个列里面的值是以SQL这几个字母开始的就算是。

为此我写了这个未完成的查询:

select code, name
  from qz_courses
##REPLACE##
order by code
/

哪些选项包含了一个WHERE子句,可以用来取代 ##REPLACE## 使得查询返回这个输出:

CODE       NAME
---------- ------------------------------
SQL10      RANGE versus ROWS
SQL16      Linear regression

(A)
where code like '^SQL'

(B)
where code like 'SQL%'

(C)
where code like '%SQL%'

(D)
where instr(code, 'SQL') = 0

(E)
where instr(code, 'SQL') = 1

(F)
where instr(code, 'SQL') > 0

(G)
where substr(code, 0, 3) = 'SQL'

(H)
where substr(code, 1, 3) = 'SQL'

(I)
where substr(code, 1) = 'SQL'

(J)
where code >= 'SQL' and code <  'SQM'

(K)
where code between 'SQL' and 'SQM'

(L)
where code between 'SQL' and rpad('SQL', 10, chr(255))

论坛徽章:
3
秀才
日期:2019-03-04 14:24:56秀才
日期:2019-03-04 14:25:13秀才
日期:2019-03-04 14:25:13
2#
发表于 2019-1-29 09:31 | 只看该作者
本帖最后由 mricoo 于 2019-1-29 09:38 编辑

BEGHJKL
A后面没%肯定不对
B没啥疑问
C前面有%不对
D4条记录都是有SQL这个字符串的所以不对
ESQL在最前面  所以等于1存在
F4条记录都是有SQL这个字符串所以会把4条记录都查出来
G和H是一样的,个人比较喜欢用H的方式
I是只有一个参数1,所以是截全部的
J和H是差不多的,>='SQL'把PL两条排除掉,小于或者等于SQL把L跟M之间的全查出来
L不太清楚杂用,测试了下后发现也是可以的。L题查了下资料说chr(255)是不可见字符,最后的结果应该是SQL开头的所有字符串都应该可以那就跟J和H差不多了

使用道具 举报

回复
论坛徽章:
2
2009日食纪念
日期:2009-07-22 09:30:00秀才
日期:2019-03-04 14:19:22
3#
发表于 2019-1-29 09:40 | 只看该作者
BEGHJKL
A.  不是以SQL 开头
B.  满足以sql 开头的任何字符串
C.  是包含SQL的字符串。
D.  instr的计数开始不为0
E. 满足以sql 开头的任何字符串
F. 包含sql 的任何字符串
G. 取字符换从第一个字符开始,长度为3的字符
H. 取字符换从第一个字符开始,长度为3的字符
I. 只能获取整个字符为SQL的字符串
J. K,L的原理都一样,都是字符串的比较。都满足。

使用道具 举报

回复
论坛徽章:
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
4#
发表于 2019-1-29 11:07 | 只看该作者
最常用的写法,就是 B 和 H

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期: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
5#
 楼主| 发表于 2019-1-30 05:24 | 只看该作者
答案BEGHJKL, 3楼得奖。2楼以后请不要编辑你的原帖,你可以发新帖进行纠正。

A:
用一个插入符号(^)来表示锚定到文本开头,这是规则表达式的语法。这适用于REGEXP_LIKE但不适用于LIKE。 这个选项不会返回任何数据。
B: (推荐)
在LIKE中,%是用于获取以SQL开头的所有内容的正确通配符。 优化器还会识别出你正在搜索具有特定前缀的字符串,它可能会在索引上使用RANGE SCAN,假如它看起来是最快的选择的话。
C: 将%通配符放在字符串的前后就会使得它搜索包含SQL的任何东西,而不是以SQL开头,所以这会错误地返回四行,因为PL/SQL课程也在代码中含有SQL字样。
D: INSTR会返回CODE文本中的SQL的位置,如果找不到SQL就返回0。所以此处我们实际上请求的是不包含SQL的CODE。因为所有数据都包含SQL, 这个选项不会返回任何数据。
E: 然而,如果请求的是那些在CODE文本中SQL的位置为1的记录,则会返回正确输出。但是用这种方法,优化器就不能够使用索引,它会强制(在表上或者索引上)全扫描。
F: 位置大于零就相当于在CODE的文本中的某处含有SQL,这种情况下会返回所有记录。
G: 在SQL的字符串函数中,字符串中的字符位置是从1开始算的(这不像其他语言,位置是从0开始),所以在理论上说,这个选项应该出错,因为我们问的是从位置0开始的三个字符是否和SQL匹配。但是如果你将0作为位置参数传递给SUBSTR, 那么SUBSTR就会当作1来处理,所以这实际上是可以的,和下一选项相同。
H: 我们问的是CODE文本的前三个字符是否和SQL相等,所以这是可行的,会给出正确输出。但是就如同INSTR不能用上索引范围扫描,这个也会执行全扫描。
I: 当我们忽略SUBSTR的第三个参数,我们就没有说明要返回多少个字符,所以数据库会返回从指定位置一直到字符串末尾的所有字符。因为我们请求的是从位置1开始的所有字符,此处的SUBSTR返回的是整个字符串。因为我们在CODE中没有恰好等于SQL的课程,这个选项不会返回任何数据。
J: 利用这个方法我们可以明确指明所需要的字符的范围。因为M在L后面,利用这个“远低于SQM”的方法会给我们截止于SQM但不包含SQM的字符串,这恰好就是我们所要的。这个选项也允许优化器利用潜在的索引范围扫描。

K: 这个选项用了BETWEEN,它等同于"code >= 'SQL' and code <= 'SQM'", 这对我们的数据是可以的(所以这个选项是对的),但它不是对于所有潜在的数据都是100%正确——如果有一个课程的代码恰好等于SQM, 它就会被错误第包含到输出里面。
L: 我们可以修复前一选项,方法是将SQM替换成以SQL开头的可能的最大字符串(和我们要比较的列同等长度)。在一个单字节数据库中(这是我们题目的假定),这可以通过一系列的CHR(255)来实现。

使用道具 举报

回复
论坛徽章:
3
秀才
日期:2019-03-04 14:24:56秀才
日期:2019-03-04 14:25:13秀才
日期:2019-03-04 14:25:13
6#
发表于 2019-1-30 09:00 | 只看该作者
newkid 发表于 2019-1-30 05:24
答案BEGHJKL, 3楼得奖。2楼以后请不要编辑你的原帖,你可以发新帖进行纠正。A:用一个插入符号(^)来表示锚 ...

好的,重在参与

使用道具 举报

回复

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

本版积分规则 发表回复

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