leetcode数据库题解(一)

作者: Lykit01 | 来源:发表于2018-12-23 21:48 被阅读0次

    本想很早就写leetcode数据库的题解的,但是被其他事耽搁了,现在开始写!
    凡例:1.对于题目只放出题目的编号、题目和链接;
    2.题目按照通过率排序;
    3.解答会放出mysql语言的代码,其他语言我没写过,就不放出来了。

    #595大的国家

    这题比较简单,用个where查询就可以了

    select name,population,area from World where population>25000000 or area>3000000;
    

    #182查找重复的电子邮箱

    这题也不难,用count函数,重复的邮箱会大于1,注意用having关键词时必须和分组group by一起使用,并且放在group by之后。

    select Email from Person group by Email group by Email having count(Email)>1;
    

    当然这题也可以用子查询,即先计数,创造一个临时表。注意,这里子查询的表要给出一个别名,我们记为counting。

    select Email from (select Email , count(Email) as num from Person group by Email) as counting where num>1;
    

    #627交换性别

    这题考update和case的用法。

    update salary set sex=case sex when 'm' then 'f' else 'm';
    

    当然也可以这么写。

    update salary set sex=case sex when 'm' then 'f' when 'f' then 'm';
    

    用if也是可以的。if函数和excel的if函数很像。

    update salary set sex=if(sex='m' ,'f' , 'm');
    

    #620有趣的电影

    这题也很简单,用where判断条件就行了。注意结果要按降序(desc)排列,升序是asc。判断奇数用mod函数也可以:MOD(id,2)=1。不等于用<>也可以,但是大多数语言只支持'!='。

    select * from cinema where id%2==1 and description!='boring' order by rating desc;
    

    #175组合两个表

    这题也很基础,考组合的用法。这题要求无论Person是否有地址信息,都需要给Person提供地址信息。也就是说即使Person中有些条目在Address中找不到匹配的,也要选出来,那么符合条件的就是左交(left join)了。

    select Person.FirstName , Person.LastName , Address.City,Address.State from Person left join Address on Person.PersonId=Address.Person order by Person.PersonId;
    

    #181超过经理收入的员工

    这类题要构造临时表,即把一个表用别名复制几次。第一个筛选员工,第二个表选出对应的manager。

    select e1.Name as Employee from Employee e1,Employee e2 where e1.Salary>e2.Salary where e1.ManagerId=e2.Id; 
    

    #183从不订购的客户

    这题要从Customers表中筛选不在Orders表中的客户,可以延续上题的思路,先左交,再选出customerid为null的顾客。

    select tmp.Name as Customers from 
    (select Customers.Name,Orders.CustomerId as order as Customers from Customers left join Orders on Customers.Id=Orders.CustomerId) as tmp where tmp.order is null;
    

    其实我上面写繁琐了,不需要用子查询,直接从组合的表中选择就好了。看别人的写法:

    select c.Name as Customers from
     Customers c left join Orders o on c.Id=o.CustomerId 
    where o.CustomerId is NULL;
    

    注意这里在组合表后直接用了where,而且组合表中为空的CustomerId也可以用o.CustomerId引用。
    不使用左交,用not in判断条件也是可以的。这种方法也比上面的简洁。

    select Customers.Name as Customers from Customers where Customers.Id not in (select CustomerId from Orders);
    

    #626换座位

    这题比较难,需要用case和子查询。注意,counts要在后面单独算出来,因为前面id,student是绑定的,用count(student)是不行的,因为在select中的count(student)就限定了结果只能有1行。

    select(case
          when id%2!=0 and id!=counts then id+1
          when id%2!=0 and id=counts then id
          else id-1 end)
          as id,student
          from seat,(select count(student) as counts from seat)seatCount 
          order by id;
    

    #178分数排名

    这题也有难度,也要构建临时表。还是要注意不要在select下直接写count,要放在子查询下。
    第一种思路是查询有多少不重复的分数大于当前分数。

    select s1.Score,
    (select count(distinct s2.Score)+1 from Scores s2 where s2.Score>s1.Score) as Rank 
    from Scores s1 order by s1.Score desc;
    

    第二种思路是构建两个变量,其中一个变量代表Rank的值,另一个变量代表上一个Score的值,当Score按从高到低排序后,只需要比较前一个 Score是否等于当前Score,如果相等,则Rank不变,如果不想等,则Rank加1。用户变量这一块我也不是非常清楚,这里先看看大神的代码吧。

    select 
        Score,  
        @i := @i + (@j <> (@j:= Score)) as Rank 
    from 
        Scores, (select @i:=0,@j:=-1) init 
    order by Score desc
    

    #196删除重复的电子邮箱

    delete p1 from Person p1,Person p2 where p1.Email=p2.Email and p1.Id>p2.Id;
    

    这题用到的delete和我们学的有点不一样,一般delete后面是不带表名的,表名在from后,这里from后有两个表名,指明p1就删除p1的内容并返回p1,p2同理,如果同时指明p1和p2,返回的是p1,p2各自删除后的内交inner join,如下图:


    同时删除p1,p2
    运行结果

    今天就写这么多!寒冬也要加油呀!最后喝点鸡汤,非常感谢陌生的你(id:然)给我的安慰!


    日记

    相关文章

      网友评论

        本文标题:leetcode数据库题解(一)

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