【SQL高频练习带刷】day8:高级字符串函数 / 正则表达式 / 子句

题目一:修复表中的名字

题目要求:

编写解决方案,修复名字,使得只有第一个字符是大写的,其余都是小写的。

返回按 user_id 排序的结果表。

表结构:

 运行结果示例:

思路:

        本题考察了SQL中常用的几个字符串函数:

  • CONCAT 用来拼接字符串 concat(s1,s2,s3,....)
  • LEFT 从左边截取字符  lfet(s,1)
  • RIGHT 从右边截取字符 right("ABC",1)
  • UPPER 变为大写  upper("ade")
  • LOWER 变为小写 lower("ASA")
  • LENGTH 获取字符串长度 length("asdse")

运行代码示例:

select user_id,CONCAT(UPPER(LEFT(name,1)), LOWER(right(name,LENGTH(name) -1))) as name
from Users
ORDER BY user_id 

题目二:患某种疾病的患者

题目要求:

查询患有 I 类糖尿病的患者 ID (patient_id)、患者姓名(patient_name)以及其患有的所有疾病代码(conditions)。I 类糖尿病的代码总是包含前缀 DIAB1 。

按 任意顺序 返回结果表。

表结构:

 运行结果示例:

思路:

        这道题直接使用正则匹配就可以,也可以简单点用like关键字,但是需要注意,不能用“%DIAB1%”去做,因为题目要求必须以DIAB1作为开头,这又包括了它是第一个单词开头或者非第一个单词的单词开头的情况。我们可以用“conditions like "DIAB1%" or conditions like "% DIAB1%"”来做。

运行代码示例:

select patient_id , patient_name , conditions
from Patients
where conditions like "DIAB1%" or conditions like "% DIAB1%"

题目三:删除重复的电子邮箱

题目要求:

编写解决方案 删除 所有重复的电子邮件,只保留一个具有最小 id 的唯一电子邮件。

(对于 SQL 用户,请注意你应该编写一个 DELETE 语句而不是 SELECT 语句。)

(对于 Pandas 用户,请注意你应该直接修改 Person 表。)

运行脚本后,显示的答案是 Person 表。驱动程序将首先编译并运行您的代码片段,然后再显示 Person 表。Person 表的最终顺序 无关紧要 。

表结构:

 运行结果示例:

思路:

        首先,我们要明确一下删除语句。

DELETE FROM 表名称 WHERE 列名称 = 值

        之后我们只需要考虑如何筛选出“邮箱值重复”且“id不为最小”的数据。emm好像没什么思路,那么我们反向思考,寻找“邮箱唯一”或“邮箱重复且id最小”的数据id,似乎可以考虑一下group by子句?我们按照邮箱分组,就可以得到所有重复/不重复的邮箱,再从每组中找到最小的id不就行了?如果邮箱唯一,也满足上述条件,似乎没什么问题。得到这些id后,我们只需要删除不在这些id序列中的id数据即可。

        但是当我们按照如上思路写出代码时,会报错,提示delete 的where中不能有子查询。所以我们需要给(select min(Id) as id from Person group by Email)赋个别名A,再从A表中获取id。

delete from Person
where id not in 
(select min(Id) as id from Person group by Email) 

运行代码示例:

delete from Person
where id not in (
    select need.id from (select min(Id) as id from Person group by Email) as need)

题目四:第二高的薪水

题目要求:

查询并返回 Employee 表中第二高的薪水 。如果不存在第二高的薪水,查询应该返回 null(Pandas 则返回 None) 。

表结构:

 运行结果示例:

思路:

        这道题目难度虽然是中等但感觉还好....可能是因为小的细节点太多了。比如首先筛选出第二高的薪资,就需要使用order by和limit进行;其次在排序时,我们要对相同的值进行去重;最后就是如果不存在第二高的薪水,我们要使用ifnull再进行一个判断,将返回值改为null。

运行代码示例:

# Write your MySQL query statement below
select ifnull((select distinct salary 
from Employee
order by salary desc
limit 1,1),null) SecondHighestSalary

题目五:按日期分组销售产品

题目要求:

编写解决方案找出每个日期、销售的不同产品的数量及其名称。
每个日期的销售产品名称应按词典序排列。
返回按 sell_date 排序的结果表。

表结构:

 运行结果示例:

思路:

        这道题考察是主要是分组拼接函数 group_concat()。使用方法是

GROUP_CONCAT(
    DISTINCT expression1
    ORDER BY expression2
    SEPARATOR sep
);

运行代码示例:

select sell_date,count(distinct product) num_sold , group_concat(
        distinct product
        order by product
        separator ','
    ) products
from Activities
group by sell_date
order by sell_date

题目六:列出指定时间段内所有下单产品

题目要求:

写一个解决方案,要求获取在 2020 年 2 月份下单的数量不少于 100 的产品的名字和数目。

返回结果表单的 顺序无要求 

表结构:

 运行结果示例:

思路:

        这道题目并不难,主要是对时间条件的筛选如何做,我们使用大小比较、like、函数转换都可以。此外还要注意对于unit的比较要放在having子句中进行。

运行代码示例:

select product_name,sum(unit) as unit
from Orders
left join Products
using(product_id)
where order_date between '2020-02-01' and '2020-02-29'
group by product_name
having sum(unit)>=100 

题目七:查找拥有有效邮箱的用户

题目要求:

编写一个解决方案,以查找具有有效电子邮件的用户。

一个有效的电子邮件具有前缀名称和域,其中:

  1.  前缀 名称是一个字符串,可以包含字母(大写或小写),数字,下划线 '_' ,点 '.' 和/或破折号 '-' 。前缀名称 必须 以字母开头。
  2.  为 '@leetcode.com' 。

以任何顺序返回结果表。

表结构:

 运行结果示例:

思路:

        题目考察的是正则表达式。

  • ^:这个符号表示字符串的开始。
  • [a-zA-Z]:这个部分匹配任何单个字母,无论大小写。
  • [a-zA-Z0-9_.-]:这个部分匹配任何数量(包括零个)的字母,数字,下划线,点或破折号。星号表示前面的字符可以出现任意次数。
  • \@leetcode\.com:这个部分匹配"@leetcode.com"字符串。在这里,\用于转义特殊字符@和.,使它们被视为普通字符而不是正则表达式的特殊符号。
  • $:这个符号表示字符串的结束。

运行代码示例:

SELECT user_id, name, mail
FROM Users
-- `@`字符需要转义,因为它在某些正则表达式中具有特殊意义
WHERE mail REGEXP '^[a-zA-Z][a-zA-Z0-9_.-]*\\@leetcode\\.com$';
"SELECT * FROM ( select invono1,date1, vendorid1,vendor, sum( IFNULL(qty1,0))qty1,sum( IFNULL(weight1,0) )weight1,(sum( IFNULL(amt,0))+0) amt3,sum( IFNULL(prncount1,0) )prncount1,round(sum( IFNULL(amt,0))/sum( IFNULL(qty1,0)),3)junjia,round(sum( IFNULL(weight1,0))*1000/sum( IFNULL(qty1,0)),2)danzhong,sum( IFNULL(jianshu1,0) )jianshu1,sum( IFNULL(baoshu1,0) )baoshu1,sum(jianshu1 + baoshu1) AS jianbao1 from ( select subptin1.invono invono1,subptin1.date date1,subptin1.vendorid vendorid1, vendor,subptin1.createid createid1,subptin1.lconfirma lconfirma1,subptou2.model model1,subptou2.sort sort1,subptou2.color color1,subptou2.size size1,subptou2.platsort platsort1,subptou2.cola cola1, subptin2.qty qty1,subptin2.weight weight1,subptin2.unitpri unitpri1,round(subptin2.qty*subptin2.unitpri,2) amt,subptin2.mem mem1,subptin1.prncount prncount1,subptin2.add003 jianshu1,subptin2.add004 baoshu1,(subptin2.add003+subptin2.add004)jianbao1 ,subptin1.createdt createdt1,subptin1.prndatetime prndatetime1,subptin1.confirmadt confirmadt1, subptin1.editordt editordt1 from subptin1 inner join subptin2 on subptin2.invono=subptin1.invono inner join subptou2 on subptou2.mid=subptin2.id inner join subptou1 on subptou1.invono=subptou2.invono left join subvendor1 on subvendor1.vendorid=subptin1.vendorid where (case when (LENGTH('"+alltrim(acond[1,1])+"')=0) then subptin1.date=date_add(curdate(),interval 0 day) else (subptin1.date between '"+alltrim(acond[1,1])+"' and '"+alltrim(acond[1,2])+"') end) )as tab1 GROUP BY CASE WHEN LENGTH('"+alltrim(acond[2,1])+"') = 0 THEN vendorid1 ELSE invono1 END union all select '送货合计','','','',concat(sum(subptin2.qty),'个') ,concat(sum(subptin2.weight),'公斤'),concat(sum(round(subptin2.qty*subptin2.unitpri,2)),'元') ,concat(sum(subptin1.prncount),'次'),concat(round(sum(round(subptin2.qty*subptin2.unitpri,2))/sum(subptin2.qty),3),'均价元'),concat(round(sum(subptin2.weight)*1000/sum(subptin2.qty),2),'克'),concat(sum(subptin2.add003),'件'),concat(sum(subptin2.add004),'包'),concat(sum(subptin2.add003+subptin2.add004),'件包') from subptin1 inner join subptin2 on subptin2.invono=subptin1.invono inner join subptou2 on subptou2.mid=subptin2.id inner join subptou1 on subptou1.invono=subptou2.invono left join subvendor1 on subvendor1.vendorid=subptin1.vendorid where (case when (LENGTH('"+alltrim(acond[1,1])+"')=0) then subptin1.date=date_add(curdate(),interval 0 day) else (subptin1.date between '"+alltrim(acond[1,1])+"' and '"+alltrim(acond[1,2])+"') end) ) AS t ORDER BY CASE WHEN invono1 = '送货合计' THEN 1 ELSE 0 END, CASE WHEN invono1 <> '送货合计' THEN t.amt3 END ASC " 强制atm3转成数值,才能排序
08-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值