美文网首页
完结篇:LeetCode数据库最新44题190528Oracle

完结篇:LeetCode数据库最新44题190528Oracle

作者: albert184 | 来源:发表于2019-05-28 23:26 被阅读0次

    排版好有颜色的文章在公众号“八哥的成长心路札记”上有,微信号是bager1912。

    以下题目均来自力扣(LeetCode)官网和其他网站,仅用作数据库爱好者学习交流,严禁进行商业及任何非法用途。

    603. 连续空余座位

    几个朋友来到电影院的售票处,准备预约连续空余座位。

    你能利用表cinema,帮他们写一个查询语句,获取所有空余座位,并将它们按照 seat_id 排序后返回吗?

    | seat_id | free |

    |---------|------|

    | 1      | 1    |

    | 2      | 0    |

    | 3      | 1    |

    | 4      | 1    |

    | 5      | 1    |

     对于如上样例,你的查询语句应该返回如下结果。

    | seat_id |

    |---------|

    | 3      |

    | 4      |

    | 5      |

    注意:

    seat_id 字段是一个自增的整数,free 字段是布尔类型('1' 表示空余, '0' 表示已被占据)。

    连续空余座位的定义是大于等于 2 个连续空余的座位。

    selectdistincta.seat_id

    fromcinema a,cinema b

    where(a.seat_id-1=b.seat_idora.seat_id+1=b.seat_id)and(a.free=1andb.free=1)

    orderbya.seat_id;

    607. 销售员

    描述

    给定 3 个表:salesperson,company,orders。

    输出所有表salesperson中,没有向公司 'RED' 销售任何东西的销售员。

    解释

    输入

    表:salesperson

    +----------+------+--------+-----------------+-----------+

    | sales_id | name | salary | commission_rate | hire_date |

    +----------+------+--------+-----------------+-----------+

    |  1      | John | 100000 |    6          | 4/1/2006  |

    |  2      | Amy  | 120000 |    5          | 5/1/2010  |

    |  3      | Mark | 65000  |    12          | 12/25/2008|

    |  4      | Pam  | 25000  |    25          | 1/1/2005  |

    |  5      | Alex | 50000  |    10          | 2/3/2007  |

    +----------+------+--------+-----------------+-----------+

    表salesperson存储了所有销售员的信息。每个销售员都有一个销售员编号sales_id和他的名字name 。

    表:company

    +---------+--------+------------+

    | com_id  |  name  |    city    |

    +---------+--------+------------+

    |  1    |  RED  |  Boston  |

    |  2    | ORANGE |  New York |

    |  3    | YELLOW |  Boston  |

    |  4    | GREEN  |  Austin  |

    +---------+--------+------------+

    表company存储了所有公司的信息。每个公司都有一个公司编号com_id和它的名字name。

    表:orders

    +----------+------------+---------+----------+--------+

    | order_id | order_date | com_id  | sales_id | amount |

    +----------+------------+---------+----------+--------+

    | 1        |  1/1/2014 |    3    |    4    | 100000 |

    | 2        |  2/1/2014 |    4    |    5    | 5000  |

    | 3        |  3/1/2014 |    1    |    1    | 50000  |

    | 4        |  4/1/2014 |    1    |    4    | 25000  |

    +----------+----------+---------+----------+--------+

    表orders存储了所有的销售数据,包括销售员编号sales_id 和公司编号com_id。

    输出

    +------+

    | name |

    +------+

    | Amy  |

    | Mark |

    | Alex |

    +------+

    解释

    根据表orders中的订单 '3' 和 '4' ,容易看出只有 'John' 和 'Pam' 两个销售员曾经向公司 'RED' 销售过。

    所以我们需要输出表salesperson中所有其他人的名字。

    selectname

    fromsalesperson

    wheresales_idnotin(selectsales_id

    fromorders ojoincompany c

    ono.com_id=c.com_id

    wherec.name='RED');

    608. 树节点

    给定一个表tree,id是树节点的编号,p_id是它父节点的id 。

    +----+------+

    | id | p_id |

    +----+------+

    | 1  | null |

    | 2  | 1    |

    | 3  | 1    |

    | 4  | 2    |

    | 5  | 2    |

    +----+------+

    树中每个节点属于以下三种类型之一:

    叶子:如果这个节点没有任何孩子节点。

    根:如果这个节点是整棵树的根,即没有父节点。

    内部节点:如果这个节点既不是叶子节点也不是根节点。

    写一个查询语句,输出所有节点的编号和节点的类型,并将结果按照节点编号排序。上面样例的结果为:

    +----+------+

    | id | Type |

    +----+------+

    | 1  | Root |

    | 2  | Inner|

    | 3  | Leaf |

    | 4  | Leaf |

    | 5  | Leaf |

    +----+------+

    解释

    节点 '1' 是根节点,因为它的父节点是 NULL ,同时它有孩子节点 '2' 和 '3' 。

    节点 '2' 是内部节点,因为它有父节点 '1' ,也有孩子节点 '4' 和 '5' 。

    节点 '3', '4' 和 '5' 都是叶子节点,因为它们都有父节点同时没有孩子节点。

    样例中树的形态如下:

    1

    /  \

    2      3

    /  \

    4      5

    注意

    如果树中只有一个节点,你只需要输出它的根属性。

    selectid,'Root'Type

    fromtree

    wherep_idisnull

    union

    selectid,'Inner'Type

    fromtree

    whereidin(selectdistinctp_id

    fromtree

    wherep_idisnotnull)andp_idisnotnull

    union

    selectid,'Leaf'Type

    fromtree

    whereidnotin(selectdistinctp_id

    fromtree

    wherep_idisnotnull)andp_idisnotnull

    orderbyid;

    610. 判断三角形

    一个小学生 Tim 的作业是判断三条线段是否能形成一个三角形。

    然而,这个作业非常繁重,因为有几百组线段需要判断。

    假设表table保存了所有三条线段的三元组 x, y, z ,你能帮 Tim 写一个查询语句,来判断每个三元组是否可以组成一个三角形吗?

    | x  | y  | z  |

    |----|----|----|

    | 13 | 15 | 30 |

    | 10 | 20 | 15 |

    对于如上样例数据,你的查询语句应该返回如下结果:

    | x  | y  | z  | triangle |

    |----|----|----|----------|

    | 13 | 15 | 30 | No      |

    | 10 | 20 | 15 | Yes      |

    selecttriangle.*,(casewhenx+y>zandx+z>yandy+z>xthen'Yes'else'No'end)"triangle"

    fromtriangle;

    这个LeetCode让我有点郁闷,把表名字命名为table,也是无语了,看了评论说是表名为triangle。

    612. 平面上的最近距离

    表point_2d保存了所有点(多于 2 个点)的坐标 (x,y) ,这些点在平面上两两不重合。

    写一个查询语句找到两点之间的最近距离,保留 2 位小数。

    | x  | y  |

    |----|----|

    | -1 | -1 |

    | 0  | 0  |

    | -1 | -2 |

    最近距离在点 (-1,-1) 和(-1,2) 之间,距离为 1.00 。所以输出应该为:

    | shortest |

    |----------|

    | 1.00    |

    注意:任意点之间的最远距离小于 10000 。

    selectround(SQRT(min(power((p1.x-p2.x),2)+power((p1.y-p2.y),2))),2)"shortest"

    frompoint_2d p1joinpoint_2d p2

    onp1.x!=p2.xorp1.y!=p2.y;

    613. 直线上的最近距离

    表point保存了一些点在 x 轴上的坐标,这些坐标都是整数。

    写一个查询语句,找到这些点中最近两个点之间的距离。

    | x  |

    |-----|

    | -1  |

    | 0  |

    | 2  |

    最近距离显然是 '1' ,是点 '-1' 和 '0' 之间的距离。所以输出应该如下:

    | shortest|

    |---------|

    | 1      |

    注意:每个点都与其他点坐标不同,表table不会有重复坐标出现。

    进阶:如果这些点在 x 轴上从左到右都有一个编号,输出结果时需要输出最近点对的编号呢?

    selectmin(abs(p1.x-p2.x))"shortest"

    frompoint p1,point p2

    wherep1.x!=p2.x;

    614. 二级关注者

    在 facebook 中,表follow会有 2 个字段:followee,follower,分别表示被关注者和关注者。

    请写一个 sql 查询语句,对每一个关注者,查询他的关注者数目。

    比方说:

    +-------------+------------+

    | followee    | follower  |

    +-------------+------------+

    |    A      |    B      |

    |    B      |    C      |

    |    B      |    D      |

    |    D      |    E      |

    +-------------+------------+

    应该输出:

    +-------------+------------+

    | follower    | num        |

    +-------------+------------+

    |    B      |  2        |

    |    D      |  1        |

    +-------------+------------+

    解释:

    B 和 D 都在在follower字段中出现,作为被关注者,B 被 C 和 D 关注,D 被 E 关注。A 不在follower字段内,所以A不在输出列表中。

    注意:

    被关注者永远不会被他 / 她自己关注。

    将结果按照字典序返回。

    selectdistinctf2.follower,f1.num

    from(selectfollowee,nvl(count(distinctcn),0)num

    from

    (selectfollowee,concat(followee,follower) cn

    fromfollow)

    groupbyfollowee) f1joinfollow f2

    onf1.followee=f2.follower

    orderbyf2.follower;

    这道题怎么改提交都不通过,很奇怪,不知道哪个地方有问题,而相似的mysql版本的却能通过,知道的朋友麻烦告诉我下,谢谢?

    SELECTDISTINCTf2.follower,f1.num

    FROM(SELECTfollowee,IFNULL(COUNT(DISTINCTfollowee,follower),0)ASnum

    FROMfollow

    GROUPBYfollowee) f1

    INNERJOINfollow f2

    ONf1.followee = f2.follower

    ORDERBYf2.follower

    ;

    615. 平均工资:部门与公司比较

    给如下两个表,写一个查询语句,求出在每一个工资发放日,每个部门的平均工资与公司的平均工资的比较结果 (高 / 低 / 相同)。

    表:salary

    | id | employee_id | amount | pay_date  |

    |----|-------------|--------|------------|

    | 1  | 1          | 9000  | 2017-03-31 |

    | 2  | 2          | 6000  | 2017-03-31 |

    | 3  | 3          | 10000  | 2017-03-31 |

    | 4  | 1          | 7000  | 2017-02-28 |

    | 5  | 2          | 6000  | 2017-02-28 |

    | 6  | 3          | 8000  | 2017-02-28 |

    employee_id字段是表employee中employee_id字段的外键。

    | employee_id | department_id |

    |-------------|---------------|

    | 1          | 1            |

    | 2          | 2            |

    | 3          | 2            |

    对于如上样例数据,结果为:

    | pay_month | department_id | comparison  |

    |-----------|---------------|-------------|

    | 2017-03  | 1            | higher      |

    | 2017-03  | 2            | lower      |

    | 2017-02  | 1            | same        |

    | 2017-02  | 2            | same        |

    解释

    在三月,公司的平均工资是 (9000+6000+10000)/3 = 8333.33...

    由于部门 '1' 里只有一个employee_id为 '1' 的员工,所以部门 '1' 的平均工资就是此人的工资 9000 。因为 9000 > 8333.33 ,所以比较结果是 'higher'。

    第二个部门的平均工资为employee_id为 '2' 和 '3' 两个人的平均工资,为 (6000+10000)/2=8000 。因为 8000 < 8333.33 ,所以比较结果是 'lower' 。

    在二月用同样的公式求平均工资并比较,比较结果为 'same' ,因为部门 '1' 和部门 '2' 的平均工资与公司的平均工资相同,都是 7000 。

    selectdt"pay_month",department_id"department_id",casewhenbv>avthen'higher'

    whenbv=avthen'same'

    else'lower'end"comparison"

    from(selectdt,department_id,av,avg(amount) bv

    from(selectto_char(pay_date,'YYYY-MM') dt,avg(amount) av

    fromsalary

    groupbyto_char(pay_date,'YYYY-MM')) s,salary s1,employee e

    wheres1.employee_id=e.employee_idands.dt=to_char(s1.pay_date,'YYYY-MM')

    groupbydt,department_id,av)

    orderbydepartment_id,dt;

    这个地方注意下分组,group by to_char(pay_date,'YYYY-MM'),而不能是group by pay_date。

    618. 学生地理信息报告

    一所美国大学有来自亚洲、欧洲和美洲的学生,他们的地理信息存放在如下student表中。

    | name  | continent |

    |--------|-----------|

    | Jack  | America  |

    | Pascal | Europe    |

    | Xi    | Asia      |

    | Jane  | America  |

    写一个查询语句实现对大洲(continent)列的 透视表 操作,使得每个学生按照姓名的字母顺序依次排列在对应的大洲下面。输出的标题应依次为美洲(America)、亚洲(Asia)和欧洲(Europe)。数据保证来自美洲的学生不少于来自亚洲或者欧洲的学生。

    对于样例输入,它的对应输出是:

    | America | Asia | Europe |

    |---------|------|--------|

    | Jack    | Xi  | Pascal |

    | Jane    |      |        |

    进阶:如果不能确定哪个大洲的学生数最多,你可以写出一个查询去生成上述学生报告吗?

    selecta"America",b"Asia",c"Europe"

    from(selectrn,min(casecontinentwhen'America'thennameelse''end) a ,

    min(casecontinentwhen'Asia'thennameelse''end) b ,

    min(casecontinentwhen'Europe'thennameelse''end) c

    from(selectstudent.*,row_number()over(partitionbycontinentorderbyname) rn

    fromstudent)

    groupbyrn)

    orderbya,b,c;

    想了蛮久,竟然被我想出来了,不容易。这个min好像换成max也可以的。因为排序函数已经按字母顺序排好序了。但是最外面一层还需要加个order by,因为对于continent内部是排好序了,但是外面对于同一层,比如都是2,都是3的那一层并没有排序。

    既然做到了行列互换,那就再记录下今天做到的另一题,算是用sql进行多行多列相互转换,以此记录:

    导进plsql developer里如图所示:

    经过一番折腾,终于变换成功:

    八哥觉得看着不爽,一定要按照既定要求显示,于是改改代码:

    现在是对了,让我们来显示中文看看:

    这么看着很完美,八哥略有点点成就感,如果需要源代码的朋友欢迎点赞,转发,或留言(#^.^#)没有的话,八哥就私藏了哈

    619. 只出现一次的最大数字

    表my_numbers的num字段包含很多数字,其中包括很多重复的数字。

    你能写一个 SQL 查询语句,找到只出现过一次的数字中,最大的一个数字吗?

    +---+

    |num|

    +---+

    | 8 |

    | 8 |

    | 3 |

    | 3 |

    | 1 |

    | 4 |

    | 5 |

    | 6 |

    对于上面给出的样例数据,你的查询语句应该返回如下结果:

    +---+

    |num|

    +---+

    | 6 |

    注意:

    如果没有只出现一次的数字,输出null。

    selectmax(num)"num"

    frommy_numbers

    wherenumin(selectnum

    frommy_numbers

    groupbynum

    havingcount(*)=1);

    620. 有趣的电影

    某城市开了一家新的电影院,吸引了很多人过来看电影。该电影院特别注意用户体验,专门有个 LED显示板做电影推荐,上面公布着影评和相关电影描述。

    作为该电影院的信息部主管,您需要编写一个 SQL查询,找出所有影片描述为非boring(不无聊) 的并且 id 为奇数 的影片,结果请按等级rating排列。

    例如,下表cinema:

    +---------+-----------+--------------+-----------+

    |  id    | movie    |  description |  rating  |

    +---------+-----------+--------------+-----------+

    |  1    | War      |  great 3D  |  8.9    |

    |  2    | Science  |  fiction    |  8.5    |

    |  3    | irish    |  boring    |  6.2    |

    |  4    | Ice song  |  Fantacy    |  8.6    |

    |  5    | House card|  Interesting|  9.1    |

    +---------+-----------+--------------+-----------+

    对于上面的例子,则正确的输出是为:

    +---------+-----------+--------------+-----------+

    |  id    | movie    |  description |  rating  |

    +---------+-----------+--------------+-----------+

    |  5    | House card|  Interesting|  9.1    |

    |  1    | War      |  great 3D  |  8.9    |

    +---------+-----------+--------------+-----------+

    select*

    fromcinema

    whereid%2=1anddescription!='boring'

    orderbyratingdesc;

    626. 换座位

    小美是一所中学的信息科技老师,她有一张seat座位表,平时用来储存学生名字和与他们相对应的座位 id。

    其中纵列的id 是连续递增的

    小美想改变相邻俩学生的座位。

    你能不能帮她写一个 SQL query 来输出小美想要的结果呢?

    示例:

    +---------+---------+

    |    id  | student |

    +---------+---------+

    |    1    | Abbot  |

    |    2    | Doris  |

    |    3    | Emerson |

    |    4    | Green  |

    |    5    | Jeames  |

    +---------+---------+

    假如数据输入的是上表,则输出结果如下:

    +---------+---------+

    |    id  | student |

    +---------+---------+

    |    1    | Doris  |

    |    2    | Abbot  |

    |    3    | Green  |

    |    4    | Emerson |

    |    5    | Jeames  |

    +---------+---------+

    注意:

    如果学生人数是奇数,则不需要改变最后一个同学的座位。

    SELECT(CASE

    WHENMOD(id,2) =1ANDid= (SELECTCOUNT(*)FROMseat)THENid

    WHENMOD(id,2) =1THENid+1

    ElSEid-1

    END)ASid, student

    FROMseat

    ORDERBYid;

    摘自blacksheep,这个思路太好了。

    627. 交换工资

    给定一个salary表,如下所示,有 m = 男性 和 f = 女性 的值。交换所有的 f 和 m 值(例如,将所有 f 值更改为 m,反之亦然)。要求只使用一个更新(Update)语句,并且没有中间的临时表。

    注意,您必只能写一个 Update 语句,请不要编写任何 Select 语句。

    例如:

    | id | name | sex | salary |

    |----|------|-----|--------|

    | 1  | A    | m  | 2500  |

    | 2  | B    | f  | 1500  |

    | 3  | C    | m  | 5500  |

    | 4  | D    | f  | 500    |

    运行你所编写的更新语句之后,将会得到以下表:

    | id | name | sex | salary |

    |----|------|-----|--------|

    | 1  | A    | f  | 2500  |

    | 2  | B    | m  | 1500  |

    | 3  | C    | f  | 5500  |

    | 4  | D    | m  | 500    |

    updatesalary

    setsex=casesexwhen'm'then'f'

    else'm'end;

    感觉这道题应该叫交换性别,有木有。。。

    1045. Customers Who Bought All Products

    Table:Customer

    +-------------+---------+

    | Column Name | Type    |

    +-------------+---------+

    | customer_id | int    |

    | product_key | int    |

    +-------------+---------+

    product_key is a foreign key toProducttable.

    Table:Product

    +-------------+---------+

    | Column Name | Type    |

    +-------------+---------+

    | product_key | int    |

    +-------------+---------+

    product_key is the primary key column for this table.

    Write an SQL query for a report that provides the customer ids from theCustomertable that bought all the products in theProducttable.

    For example:

    Customer table:

    +-------------+-------------+

    | customer_id | product_key |

    +-------------+-------------+

    | 1          | 5          |

    | 2          | 6          |

    | 3          | 5          |

    | 3          | 6          |

    | 1          | 6          |

    +-------------+-------------+

    Product table:

    +-------------+

    | product_key |

    +-------------+

    | 5          |

    | 6          |

    +-------------+

    Result table:

    +-------------+

    | customer_id |

    +-------------+

    | 1          |

    | 3          |

    +-------------+

    The customers who bought all the products (5 and 6) are customers with id 1 and 3.

    selectdistinctcustomer_id

    fromcustomer

    whereproduct_keyin(selectproduct_key

    fromproduct)

    groupbycustomer_id

    havingcount(*)=(selectcount(*)

    fromproduct);

    这个做法在LeetCode里死活无法通过,试了好几种类似的写法,均提交失败,哪位大神更懂的给指指路,谢谢!

    1050. Actors and Directors Who Cooperated At Least Three Times

    able:ActorDirector

    +-------------+---------+

    | Column Name | Type    |

    +-------------+---------+

    | actor_id    | int    |

    | director_id | int    |

    | timestamp  | int    |

    +-------------+---------+

    timestamp is the primary key column for this table.

    Write a SQL query for a report that provides the pairs(actor_id, director_id)where the actor have cooperated with the director at least 3 times.

    Example:

    ActorDirector table:

    +-------------+-------------+-------------+

    | actor_id    | director_id | timestamp  |

    +-------------+-------------+-------------+

    | 1          | 1          | 0          |

    | 1          | 1          | 1          |

    | 1          | 1          | 2          |

    | 1          | 2          | 3          |

    | 1          | 2          | 4          |

    | 2          | 1          | 5          |

    | 2          | 1          | 6          |

    +-------------+-------------+-------------+

    Result table:

    +-------------+-------------+

    | actor_id    | director_id |

    +-------------+-------------+

    | 1          | 1          |

    +-------------+-------------+

    The only pair is (1, 1) where they cooperated exactly 3 times.

    selectactor_id,director_id

    from(selectactor_id,director_id,count(*) cn

    fromactordirector

    groupbyactor_id,director_id)

    wherecn>=3;

    至此,截止2019年05月28日,LeetCode数据库全部44题,已全部解析完毕,鉴于个人能力有限,难免会有些许差错,欢迎各位看官批评指正,提出新的想法或建议,八哥与你共同学习,一起成长!

    本专题完结!

    相关文章

      网友评论

          本文标题:完结篇:LeetCode数据库最新44题190528Oracle

          本文链接:https://www.haomeiwen.com/subject/fodstctx.html