牛客网有SQL练习题

数据类型

MYSQL笔记 - 图1

  • floatdouble都是不精确的,对精确性有要求的场景优先考虑使用DECIMAL类型(生产环境中也有放大后使用整形的案例)
  • 日期和时间类型的一般都采用DATETIME类型
  • `CREATE TABLE a LIKE b 可以创建表副本

    主键选择

    image.png

    连接

    image.png

    外键

    image.png

    WHERE和HAVING

    image.png

    LEFT函数的使用

    SELECT -> LEFT(b.transdate, 10), — 从关联表获取交易时间,并且通过LEFT函数,获取交易时间字符串的左边10个字符,得到年月日的数据

    时间函数

    image.png

    视图

    image.png

    设计范式

  • 第一范式:所有字段不可再拆

  • 第二范式:每行数据可唯一标识,所有字段不能只依赖主键的一部分
  • 第三范式:所有字段不能依赖于非主键

ER关系图和数据表的转换原则

image.png

冗余字段

image.png

非空约束

image.png
MYSQL笔记 - 图11

实战常用语法

  • 批量插入

image.png

  • 覆盖式插入

replace into ….

  • 时间差函数

timestampdiff(unit, date_expr1, date_expr2)
前早后晚为正结果

  • 判断某个字段不存在

XXX is NULL

错题本

  • 平均活跃天数和月活统计
    • distinct必须放在查询字段的开头
    • distinct只能用于select语句
    • distinct表示对后面所有参数拼接后不重复
    • 如果只希望对第一个参数生效则使用group_concat
      • select group_concat(distict(XXX)), city from tables ```sql select date_format(submit_time, ‘%Y%m’) as month, round((count(distinct uid, date_format(submit_time, ‘%y%m%d’))) / count(distinct uid), 2) as avg_active_days, count(distinct uid) as mau from exam_record where submit_time is not null and year(submit_time) = 2021 group by date_format(submit_time, ‘%Y%m’)
  1. - [和自表的平均值做比较](https://www.nowcoder.com/practice/3de23f1204694e74b7deef08922805b2?tpId=240&tags=&title=&difficulty=0&judgeStatus=0&rp=0&sourceUrl=%2Fexam%2Foj%3Fpage%3D1%26tab%3DSQL%25E7%25AF%2587%26topicId%3D240)
  2. ```sql
  3. select min(e_r.score) as min_score_over_avg
  4. from exam_record e_r join examination_info e_i
  5. on e_r.exam_id = e_i.exam_id
  6. where e_i.tag = 'SQL'
  7. and score >= (select avg(e1.score)
  8. from exam_record e1 join examination_info e2
  9. on e1.exam_id = e2.exam_id
  10. where tag = 'SQL'
  11. )
  • 获取月份的天数

    1. day(last_day(XXX_time))
  • 统计结果

    1. select ifnull(XXX,'总计')
    2. from tableb
    3. group by XXX with rollup