查看: 3517|回复: 8

[每日一题] PL/SQL Challenge 每日一题:2018-3-1 UPDATE语句

[复制链接]
论坛徽章:
527
奥运会纪念徽章:垒球
日期: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
发表于 2018-3-6 05:19 | 显示全部楼层 |阅读模式
最先答对且答案未经编辑的puber将获得纪念章一枚(答案不可编辑但可发新贴补充或纠正),其他会员如果提供有价值的分析、讨论也可获得纪念章一枚。

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

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

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

作者: Kim Berg Hanse

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

我有产品类别表以及产品表:

create table qz_categories (
   cat_id      integer primary key
, cat_name    varchar2(20)
, cat_segment varchar2(1)
, cat_class   varchar2(1)
)
/

create table qz_products (
   prod_id     integer primary key
, prod_name   varchar2(20)
, prod_cat_id integer references qz_categories
)
/

insert into qz_categories values (10, 'Stouts', 'A', 'C')
/
insert into qz_categories values (20, 'Ales'  , 'B', 'B')
/

insert into qz_products values (123, 'Bullwrinkle Black', 10)
/
insert into qz_products values (134, 'Coal-N-Tar Juice' , 10)
/
insert into qz_products values (145, 'Moonless Night'   , 10)
/
insert into qz_products values (256, 'Froghopper Brown' , 20)
/
insert into qz_products values (267, 'Auld Amber Ale'   , 20)
/
commit
/

alter table qz_products add (
   prod_segment varchar2(1)
, prod_class   varchar2(1)
)
/

我们在产品分段(segment)和等级(class)进行双重的ABC标记,这意味着根据某一个KPI(绩效指标)我们会为segment赋予A,B,C值,根据另外一个KPI为CLASS赋予A,B,C值。这样的话,我们的产品经理就可以选择切换标记哪些产品需要更多的注意,以取得更好的市场表现。

过去我们在产品类别进行这种标记,所以ABC值位于QZ_CATEGORIES表的CAT_SEGMENT 和 CAT_CLASS列。

但是现在我们需要在产品的级别进行这个标记,所以QZ_PRODUCTS被加上了两个新列PROD_SEGMENT 和 PROD_CLASS。在将来,标记将会为每个产品单独计算。

作为这两个新列的初始值,我们需要调整QZ_PRODUCTS表中的数据,使得PROD_SEGMENT 和 PROD_CLASS 会从相应产品类别的CAT_SEGMENT and CAT_CLASS 获得。

哪些选项包含的代码可以执行不出错,并且修改了QZ_PRODUCTS中的数据,使得选项执行之后,这个测试查询会返回所示的输出?

select prod_id, prod_name, prod_cat_id, prod_segment, prod_class
  from qz_products
order by prod_id
/

   PROD_ID PROD_NAME            PROD_CAT_ID P P
---------- -------------------- ----------- - -
       123 Bullwrinkle Black             10 A C
       134 Coal-N-Tar Juice              10 A C
       145 Moonless Night                10 A C
       256 Froghopper Brown              20 B B
       267 Auld Amber Ale                20 B B

(A)
update qz_products p
   set p.prod_segment = (
         select c.cat_segment
           from qz_categories c
          where c.cat_id = p.prod_cat_id
       )
/
update qz_products p
   set p.prod_class = (
         select c.cat_class
           from qz_categories c
          where c.cat_id = p.prod_cat_id
       )
/

(B)
update qz_products p
   set p.prod_segment = (
         select c.cat_segment
           from qz_categories c
          where c.cat_id = p.prod_cat_id
       )
     , p.prod_class = (
         select c.cat_class
           from qz_categories c
          where c.cat_id = p.prod_cat_id
       )
/

(C)
update qz_products p
   set (p.prod_segment, p.prod_class) = (
         select c.cat_segment, c.cat_class
           from qz_categories c
          where c.cat_id = p.prod_cat_id
       )
/

(D)
update (
   select p.prod_segment, p.prod_class, c.cat_segment, c.cat_class
     from qz_products p
     join qz_categories c
         on c.cat_id = p.prod_cat_id
)
   set prod_segment = cat_segment
     , prod_class = cat_class
/

(E)
merge into qz_products p_table
using (
   select p.rowid as rid, c.cat_segment, c.cat_class
     from qz_products p
     join qz_categories c
         on c.cat_id = p.prod_cat_id
) p_values
   on (p_table.rowid = p_values.rid)
when matched then update
   set p_table.prod_segment = p_values.cat_segment
     , p_table.prod_class = p_values.cat_class
/

(F)
merge into qz_products p
using qz_categories c
   on (c.cat_id = p.prod_cat_id)
when matched then update
   set p.prod_segment = c.cat_segment
     , p.prod_class = c.cat_class
/
论坛徽章:
142
秀才
日期:2016-01-06 14:01:09秀才
日期:2016-02-18 10:06:46秀才
日期:2016-02-18 10:08:02秀才
日期:2016-02-18 10:08:14秀才
日期:2016-03-01 09:57:08天蝎座
日期:2016-03-18 14:23:56秀才
日期:2016-03-24 09:10:24秀才
日期:2016-03-24 09:20:52秀才
日期:2016-04-21 14:08:53秀才
日期:2016-04-21 14:11:59
发表于 2018-3-6 08:42 | 显示全部楼层
以上全对ABCDEF

使用道具 举报

回复
论坛徽章:
12
懒羊羊
日期:2018-02-27 22:52:20秀才
日期:2018-05-22 15:21:20秀才
日期:2018-05-22 15:17:21技术图书徽章
日期:2018-05-22 15:17:21秀才
日期:2018-05-22 15:16:47举人
日期:2018-03-01 10:25:45秀才
日期:2018-03-01 10:21:25秀才
日期:2018-03-01 10:13:04秀才
日期:2018-03-01 10:13:04秀才
日期:2018-03-01 10:13:04
发表于 2018-3-6 09:43 | 显示全部楼层
答案:ABCDEF
ABC思路相同,写法不同而已
D、把要更新的字段和正确的结果放在一张表里面,然后进行更新
EF 利用了merge into进行更新

使用道具 举报

回复
认证徽章
论坛徽章:
34
林肯
日期:2013-07-30 18:00:55技术图书徽章
日期:2018-05-22 16:13:30秀才
日期:2018-05-22 16:13:30秀才
日期:2018-05-22 16:17:26秀才
日期:2018-07-23 13:38:29技术图书徽章
日期:2018-07-23 13:38:40秀才
日期:2018-07-23 13:38:40秀才
日期:2018-07-23 13:44:01秀才
日期:2018-08-31 10:37:01秀才
日期:2018-08-31 10:37:20
发表于 2018-3-6 10:03 | 显示全部楼层
D 写法第一次见,学习了。

使用道具 举报

回复
论坛徽章:
0
发表于 2018-3-6 15:58 | 显示全部楼层
ABCDEF 全对 有的写法没用过 很帅;不过是不是要提交一下?

使用道具 举报

回复
论坛徽章:
527
奥运会纪念徽章:垒球
日期: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
 楼主| 发表于 2018-3-7 05:03 | 显示全部楼层
答案: ABCDEF全部正确, 3楼得奖。

A: 两个UPDATE,每个用一个标量子查询修改一个列。当然可行,但是做了多余的工作。
B: 我们可以通过单个UPDATE语句对前一选项进行稍微的改善,但仍然有多余的工作,因为用了两个标量子查询。
C: 这个好多了,因为对QZ_CATEGORIES的一次查找一次性修改了两个列
D: 如果不用标量子查询查找,我们在这种情况下也可以UPDATE一个内联视图中的JOIN。它是可行的因为QZ_PRODUCTS在内联视图中的键得到了保留,这就意味着QZ_PRODUCTS的键也是JOIN的键,这是因为我们通过QZ_CATEGORIES的主键进行连接,所以我们针对QZ_PRODUCTS的每一行都不会得到多行结果。
E: 我们也可以为每个ROWID创建两个列的新值,然后用MERGE来把新值赋予两个列。
F: 前一选项也可以再改善,不用为每个ROWID创建新值,而是按照prod_cat_id上的外间来直接MERGE,这样就跳过了对QZ_PRODUCTS的不必要的重复访问。

使用道具 举报

回复
论坛徽章:
12
懒羊羊
日期:2018-02-27 22:52:20秀才
日期:2018-05-22 15:21:20秀才
日期:2018-05-22 15:17:21技术图书徽章
日期:2018-05-22 15:17:21秀才
日期:2018-05-22 15:16:47举人
日期:2018-03-01 10:25:45秀才
日期:2018-03-01 10:21:25秀才
日期:2018-03-01 10:13:04秀才
日期:2018-03-01 10:13:04秀才
日期:2018-03-01 10:13:04
发表于 2018-3-7 09:05 | 显示全部楼层
见解

使用道具 举报

回复
论坛徽章:
1
ITPUB十周年纪念徽章
日期:2011-11-01 16:21:15
发表于 2018-3-7 09:57 | 显示全部楼层
楼主每天凌晨5点发帖这是在米国啊

使用道具 举报

回复
论坛徽章:
142
秀才
日期:2016-01-06 14:01:09秀才
日期:2016-02-18 10:06:46秀才
日期:2016-02-18 10:08:02秀才
日期:2016-02-18 10:08:14秀才
日期:2016-03-01 09:57:08天蝎座
日期:2016-03-18 14:23:56秀才
日期:2016-03-24 09:10:24秀才
日期:2016-03-24 09:20:52秀才
日期:2016-04-21 14:08:53秀才
日期:2016-04-21 14:11:59
发表于 2018-3-7 10:16 | 显示全部楼层
楼上的12年老Puber了,苏大神在枫叶国啊

使用道具 举报

回复

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

本版积分规则 发表回复

【有奖讨论】解决存储挑战了解一下
奖品:米家车载空气净化器 、米家声波电动牙刷 、小米运动蓝牙耳机

在数字经济时代,井喷式增长的数据,在释放大量商业价值的同时,也随之对企业的IT基础设施带来了不容忽视的挑战!如何存储、管理、使用这些数据呢?这是一条比以往更艰难的路~

活动时间:9月20日-10月11日

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