力扣高频 SQL 50 题(基础版)|分析、题解

注意一些语法

1、group by出现在having前面,但是having中所使用的聚合必须是select中的

2、date类型之间的比较:datediff()= 差的绝对值 or 用字符框起来比较边界

3、算日期长度需要相减之后加一

4、round(, n)n默认是0,到最近的整数

5、 几个算percentage的题目都要好好看


题目

sql 复制代码
-- 注意left join
-- 基准是求quality的name列
select q.query_name, q.quality, round(ifnull(100 *p.poor_query / q.total, 0), 2) as poor_query_percentage
from(
    select query_name, round(sum(rating / position) / count(*), 2) as quality, count(*) as total
    from Queries
    group by query_name
) as q
left join (
    select query_name, count(*) as poor_query
    from Queries
    where rating < 3
    group by query_name
) as p 
on q.query_name = p.query_name
where q.query_name is not null

sql 复制代码
# Write your MySQL query statement below
select DATE_FORMAT(trans_date, '%Y-%m') as month,  -- 注意时间的提取格式
       country,
       count(*) as trans_count,
       count(case when state = 'approved' then 1 else null end) as approved_count,
       sum(amount) as trans_total_amount,
       sum(case when state = 'approved' then amount else 0 end) as approved_total_amount
from Transactions
group by month, country

sql 复制代码
-- min提取最小的一个日期作为注册时间
-- 注意在这里sum和count的区别:count统计行数,sum统计括号里的数字累计和,
-- 所以,如果让满足条件的case为1,不满足的为0,将他们sum之后得到的就是满足条件的总数,除以全部的个数(行数,count)得到比例
-- 注意,百分比的100* 应该写在round函数里面,因为结果需要保留2位
WITH FirstEvent AS (
    SELECT player_id, MIN(event_date) AS first_event_date
    FROM Activity
    GROUP BY player_id
)
SELECT 
    ROUND(SUM(CASE 
                WHEN DATEDIFF(a.event_date, fe.first_event_date) = 1               THEN 1 
                ELSE 0 
              END) / COUNT(DISTINCT a.player_id), 2) AS fraction
FROM Activity a
JOIN FirstEvent fe
  ON a.player_id = fe.player_id;

sql 复制代码
-- 首先选出最早的日期,这里用all
-- 然后case when将满足条件的标记为1,sum之后的结果除以总行
-- 注意,这里已经用最早的一天筛选出了全部顾客第一天的日期,所以同时,顾客的id也是distinct的
select round(100 * sum(case when d1.order_date = d1.customer_pref_delivery_date then 1 else 0 end) / count(*), 2) as immediate_percentage
from Delivery d1
where d1.order_date <= all(
    select order_date 
    from Delivery d2 
    where d1.customer_id = d2.customer_id
)

sql 复制代码
-- 注意productid可能在p中但是不在s中,所以不能只用not in来约束
-- having放在 where 和 group 后面
select p.product_id, p.product_name
from Product p, Sales s
where p.product_id = s.product_id
group by p.product_id
having min(sale_date) >= '2019-01-01' and max(sale_date) <= '2019-03-31'

sql 复制代码
-- max函数在没有值的时候返回null
select max(n.num) as num
from (
    select num
    from MyNumbers
    group by num
    having count(*) = 1
) n

sql 复制代码
-- 注意group by 和 count的顺序以及作用对象。这里group by作用于后面的count聚合函数,但是需要写在前面
-- 本题customer表格可能会出现重复,所以count 中需要加 distinct
select customer_id
from Customer 
group by customer_id
having count(distinct product_key) = (select count(*) from Product)

sql 复制代码
-- 对于异步行,一般是需要用自查询,需要创建多个表
select DISTINCT l1.Num AS ConsecutiveNums
from Logs l1, Logs l2, Logs l3
where l1.Id = l2.Id - 1
  and l2.Id = l3.Id - 1
  and l1.num = l2.num
  and l2.num = l3.num

sql 复制代码
-- 对于同行的比较和 case when 表达式
select x, y, z, 
case when x + y > z and x + z > y and z + y > x then 'Yes' else 'No' end as 'Triangle'
from Triangle

sql 复制代码
-- with写法和之前的一道题一样,从重复列作为manager,null也会被返回,需要去掉
-- distinct:where会产生笛卡尔积,需要去重
select e.employee_id, e.name, m.reports_count, m.average_age
from Employees e
join (
select distinct reports_to as managerid, round(sum(age) / count(*)) as average_age, count(*) as reports_count
from Employees 
where reports_to is not null
group by reports_to) m
on e.employee_id = m.managerid
order by e.employee_id
相关推荐
电子_咸鱼4 小时前
LeetCode——Hot 100【电话号码的字母组合】
数据结构·算法·leetcode·链表·职场和发展·贪心算法·深度优先
仰泳的熊猫4 小时前
LeetCode:785. 判断二分图
数据结构·c++·算法·leetcode
微笑尅乐6 小时前
中点为根——力扣108.讲有序数组转换为二叉搜索树
算法·leetcode·职场和发展
夏鹏今天学习了吗7 小时前
【LeetCode热题100(46/100)】从前序与中序遍历序列构造二叉树
算法·leetcode·职场和发展
吃着火锅x唱着歌7 小时前
LeetCode 2389.和有限的最长子序列
算法·leetcode·职场和发展
与衫8 小时前
在 VS Code 里看清你的数据流向:Gudu SQL Omni 实测体验
数据库·sql
SirLancelot19 小时前
StarRocks-基本介绍(一)基本概念、特点、适用场景
大数据·数据库·数据仓库·sql·数据分析·database·数据库架构
一只鱼^_11 小时前
第 167 场双周赛 / 第 471 场周赛
数据结构·b树·算法·leetcode·深度优先·近邻算法·迭代加深
wudl556612 小时前
Flink SQL 窗口函数详细
sql·flink·linq