当前位置:   article > 正文

每日刷力扣SQL题(二)

每日刷力扣SQL题(二)

1211.查询结果的质量和占比

本题主要考察在MYSQL内做简单的计算操作,比如求和、平均值等,

计算质量 可以用AVG()函数求出

计算劣质查询百分比 可以用SUM和IF

最后不要忘记使用ROUND()函数将结果四舍五入到小数点后两位

  1. select Queries.query_name,
  2. ROUND(SUM(rating/position)/count(result),2 ) as quality ,
  3. ROUND(SUM(IF(rating <3 ,1 ,0)) /COUNT(*) * 100 , 2) as poor_query_percentage
  4. from Queries
  5. where query_name IS NOT NULL
  6. group by Queries.query_name

官方解答:

  1. SELECT
  2. query_name,
  3. ROUND(AVG(rating/position), 2) quality,
  4. ROUND(SUM(IF(rating < 3, 1, 0)) * 100 / COUNT(*), 2) poor_query_percentage
  5. FROM Queries
  6. Where query_name IS NOT NULL
  7. GROUP BY query_name

1193 每月交易

本题要求 查找每个月和每个国家/地区的事务数及其总金额、已批准的事务数及其总金额,我们可以将这句话拆分成几个子任务:

1、查找每个月和每个国家/地区。
数据表中的 trans_date 是精确到日,我们可以使用 DATE_FORMAT() 函数将日期按照年月 %Y-%m 输出。比如将 2019-01-02 转换成 2019-01 。

DATE_FORMAT(trans_date, '%Y-%m')

 2、查找总的事务数。

COUNT(*) AS trans_count

3、 查找总金额。

SUM(amount) AS trans_total_amount

4、 查找已批准的事物数。

COUNT(IF(state = 'approved', 1, NULL)) AS approved_count

5、 查找已批准的事物的总金额

SUM(IF(state = 'approved', amount, 0)) AS approved_total_amount

官方解答:

  1. SELECT DATE_FORMAT(trans_date, '%Y-%m') AS month,
  2. country,
  3. COUNT(*) AS trans_count,
  4. COUNT(IF(state = 'approved', 1, NULL)) AS approved_count,
  5. SUM(amount) AS trans_total_amount,
  6. SUM(IF(state = 'approved', amount, 0)) AS approved_total_amount
  7. FROM Transactions
  8. GROUP BY month, country

 我的解答:

使用切割字符的方式

  1. select left(trans_date,7) as month ,
  2. country,
  3. count(state) as trans_count,
  4. sum(if(state="approved",1,0)) as approved_count,
  5. sum(amount) as trans_total_amount,
  6. sum(if(state="approved",amount,0)) as approved_total_amount
  7. from Transactions
  8. group by month,country

1174.即时食物配送 ||

本题需要求出即时订单在所有用户的首次订单中的比例,本题最重要的就是求每一个用户的首单数据:我们使用 group by 聚合每个用户的数据,再使用 min 函数求出首单的时间。将 (customer_id, order_date) 作为查询条件,使用 where in 便可查出具体的数据。

  1. select round(
  2. sum(order_date = customer_pref_delivery_date) * 100 / count(*),
  3. 2
  4. ) as immediate_percentage
  5. from Delivery
  6. where(customer_id , order_date) in (
  7. select customer_id ,min(order_date)
  8. from Delivery
  9. group by customer_id
  10. )

550.游戏玩法分析 IV

首先,求出所有用户首次登录的第二天的时间。方法是查询出 Activity 表中每个用户的第一天时间,并加上 1.

  1. select player_id, DATE_ADD(MIN(event_date), INTERVAL 1 DAY) as second_date
  2. from Activity
  3. group by player_id

将此表命名为 Expected。随后我们要从 Activity 表中查询 event_date 与 Expected.sencond_date 重叠的部分,注意此判定要限定在用户相同的前提下。这部分用户即为在首次登录后第二天也登录了的用户:

  1. select Activity.player_id as player_id
  2. from (
  3. select player_id, DATE_ADD(MIN(event_date), INTERVAL 1 DAY) as second_date
  4. from Activity
  5. group by player_id
  6. ) as Expected, Activity
  7. where Activity.event_date = Expected.second_date and Activity.player_id = Expected.player_id

将此表命名为 Result。随后我们只需要得到 Result 表中用户的数量,以及 Activity 表中用户的数量,相除并保留两位小数即可。

select IFNULL(round(count(distinct(Result.player_id)) / count(distinct(Activity.player_id)), 2), 0) as fraction

最终组合起来

  1. # Write your MySQL query statement below
  2. select IFNULL(round(count(distinct(Result.player_id))/count(distinct(Activity.player_id)),2),0) as fraction
  3. from
  4. (
  5. select Activity.player_id as player_id
  6. from
  7. (
  8. select player_id , DATE_ADD(MIN(event_date),INTERVAL 1 DAY) AS second_date
  9. from Activity
  10. group by player_id)
  11. AS Excepted ,Activity
  12. where Activity.player_id = Excepted.player_id and Excepted.second_date = Activity.event_date
  13. )
  14. as Result ,Activity

这是官方题解的组合查询 在评论中也有比较清晰的解法,运用了自连接:

  1. SELECT ROUND(SUM(IF(DATEDIFF(event_date, first_date)= 1,1,0)) / COUNT(DISTINCT a.player_id),2) AS fraction
  2. FROM Activity AS a LEFT JOIN(
  3. SELECT player_id, min(event_date) AS first_date
  4. FROM Activity
  5. GROUP BY player_id
  6. ) T
  7. ON a.player_id = T.player_id;

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/酷酷是懒虫/article/detail/1021283
推荐阅读
相关标签
  

闽ICP备14008679号