【力扣】SQL

1667 修复表中的名字

select 
    user_id,
    concat(upper(left(name,1)),lower(right(name,length(name)-1))) as name
from Users order by user_id;

concat()函数用法:用于将两个字符串连接成一个字符串

1484 按照日期分组销售产品

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

group_concat()函数用法:数据类型表现为一对多,将“多”的一方进行连接

group_concat([DISTINCT] 要连接的字段 [Order BY ASC/DESC 排序字段] [Separator '分隔符'])

1527 患某种疾病的患者

select * from Patients where conditions regexp'\\bDIAB1'

regexp 正则表达式,注意\b 转义两次(\b 用法:用于匹配单词的开头/结尾)

1795 每个产品在不同商店的价格

select product_id,'store1' as store,store1 as price from Products 
    where store1 is not null 
union all
select product_id,'store2' as store,store2 as price from Products 
    where store2 is not null 
union all
select product_id,'store3' as store,store3 as price from Products 
    where store3 is not null 

列转行(union all)

行转列(sum+if)

SQL 行转列,列转行_万物皆可休的博客-CSDN博客_sql行转列

197 上升的温度

# 计算比昨天高温的天数id
select w1.id from Weather w1,Weather w2 
where datediff(w1.recordDate,w2.recordDate) = 1 and w1.Temperature > w2.Temperature

返回从特定日期到现在的天数:to_days("2022-07-20")

将时间/日期间隔添加到日期:adddate("2022-07-20",INTERVAL 1 day) # 2020-07-20

计算相差天数/小时数/秒数:

#计算相差天数:
select TIMESTAMPDIFF(DAY,'2019-05-20', '2019-05-21'); # 1

#计算相差小时数:
select TIMESTAMPDIFF(HOUR, '2015-03-22 07:00:00', '2015-03-22 18:00:00'); # 11

#计算相差秒数:
select TIMESTAMPDIFF(SECOND, '2015-03-22 07:00:00', '2015-03-22 7:01:01'); # 61

返回值是相差的天数:

DATEDIFF("2022-07-20","2022-07-21"); # 1

DATEDIFF("2022-07-22","2022-07-21"); # -1

从日期减去指定的时间间隔:DATE_SUB("2022-07-20",INTERVAL 2 DAY) # 2022-07-18

interval:"2022-07-21" + interval '1' day # 2022-07-22

177 第N高的薪水

这道题涉及到排序和排名,根据实际情况,排名的计数可以分成以下的情况:

① 同数不同排名:例如1000、2000、2000、4000排名为 1 2 3 4

② 同数不同排名且排名不连续:例如1000、2000、2000、4000排名为 1 2 2 4

③ 同数不同排名且排名连续:1例如1000、2000、2000、4000排名为 1 2 2 3

在mysql8.0以上可以采用内置函数:

① row_number(): 同数不同名,相当于行号,例如3000、2000、2000、1000排名后为1 2 3 4

② rank(): 同数不同排名且排名不连续,例如3000、2000、2000、1000排名后为1 2 2 4

③ dense_rank(): 同数不同排名且排名连续,例如3000、2000、2000、1000排名后为1 2 2 3

④ ntile(): 分桶排名,即首先按桶的个数分出第一二三桶,然后各桶内从1排名,实际不是很常用


另外这三个函数必须要要与其搭档over()配套使用,over()中的参数常见的有两个,分别是

partition by(按某字段切分);order by(与常规order by用法一致)也区分ASC(默认)和DESC,因为排名总得有个依据
注:下面代码仅在mysql8.0以上版本可用,最新OJ已支持。

over()函数:开窗函数,可以将数据分组查询之后再聚合

185 部门工资前三高的所有员工

前三高 = 不超过3个工资比这些值大

select Department.name as Department, Employee.name as Employee,Employee.salary as Salary
from Employee join Department on Employee.departmentId = Department.id
where  3 > (
    select count(distinct e1.salary) from Employee e1
    where e1.salary > Employee.salary and e1.departmentId = Employee.departmentId
)
# 筛选出e1中大于Employee的薪资且是同一个部门的薪资

184 部门工资最高的员工

自己写的:

select d.name as Department,e.name as Employee,e.salary as Salary 
from Employee e join Department d on e.departmentId = d.id
where e.salary in(
    select max(salary) from Employee
    group by departmentId
)

正确答案:

select 
    d.Name as Department,
    e.Name as Employee,
    e.Salary 
from 
    Employee e,Department d 
where
    e.DepartmentId=d.id 
    and
    (e.Salary,e.DepartmentId) in (select max(Salary),DepartmentId from Employee group by DepartmentId);

知识补充:

左连接:left join 返回左表当中的全部行和右表与左表字段相等的行

右连接:right join 返回右表当中的全部行和左表与右表字段相等的行

内连接:inner join 返回两个表中连接字段相等的行(两表交集)

外连接:full join 左连接+右连接

笛卡尔积:cross join

自己写的报错是因为说:子查询出来的薪资,有可能是其他组的,应该带上组id

1407 排名靠前的旅行者

# 返回的结果表单,以 travelled_distance 降序排列 
# 如果有两个或者更多的用户旅行了相同的距离, 那么再以 name 升序排列 
SELECT u.name,IFNULL(SUM(r.distance),0) travelled_distance
FROM users u
LEFT JOIN rides r ON u.id = r.user_id
GROUP BY r.user_id
ORDER BY travelled_distance DESC, u.name ASC

知识点:

IFNULL(a,b) 函数:不为空则为a,为空则为b

left join和inner join

此处不能用inner join是因为会存在null的情况,而inner join会不保存null的情况的数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值