mysql语句

本文介绍了SQL查询的执行顺序,强调了`from`、`where`、`group by`、`having`、`order by`和`limit`的顺序。讨论了连接查询的性能优化,如选择小表作为驱动表,以及使用临时表的好处。还提醒了在`order by`中使用中文字段可能遇到的问题。此外,讲解了日期格式处理、数值格式化以及数据库设计的范式理论,如1NF、2NF和3NF。最后提到了`pymsql`库的执行限制和索引创建的建议,并探讨了窗口函数的应用场景。

序 执行顺序

        from > where > group by > having > order by >limit

        执行顺序高的语句要写在执行顺序低的语句前,否则会报错。

                比如先写group by再写where就会报错

        having的作用是选择符合条件的组,也就是单位为组。

                这种写法group by score having score =  max/min(score)是错误的,因为having中

                的score不会遍历该分组,而是与select scroe from XX group by scroe类似。

1. 连接查询

    -- 选择小表放右侧,作为驱动表,以提高性能

    -- tb_college是小表,tb_student是大表

    select tb_student.stu_name, tb_college.col_name from tb_student, tb_college

    where tb_student.stu_id = tb_college.stu_id;

2. 中文字段引号

    -- mysql 8.0中, order by后面的字段如果加了引号,会导致order by失效

    select stu_height as '身高' form tb_student order by '身高' desc; -- order by 失效

    select stu_height as '身高' form tb_student order by 身高 desc; -- order by 有效

3. 临时表(待验证)

    -- (待验证) 连接查询时,构建临时表会节省资源?

    -- recommended

    select tb_college.name, ifnull(total, 0)

    from tb_college left join

    (select col_id, count(*) as total from tb_student group by col_id) tb_temp

    on tb_college.col_id = tb_temp.col_id;

        
    -- not recommended

    select tb_college.name, count(tb_student.stu_id)

    from tb_college left join tb_student on tb_college.col_id = tb_student.col_id;

4. null

-- 如果offset越界,整个select语句返回值是null, 而不是一张表
select stu_id from tb_student limit 100000, 1;

-- 而再对null进行select, 返回一张表,表中字段是null, 等同于 select null;
select (select stu_id from tb_student limit 100000, 1);

-- 如果指定一个字段,对null进行select,结果还是null, 而不是一张表
select sal from (select stu_id from tb_student limit 100000, 1);


5. 日期

-- 日期格式,加减天数不要使用+1 或-1,当日期为每月第一天和最后一天时,将不会进行跨月操作

-- 使用date_add(XXX, interval 1 day) 或 date_sub(XXX, interval 1 day)来进行日期的加减.
select t2.date from t1, t2
where t2.date = date_add(t1.date, interval 1 day);

-- 使用datediff(XXX, YYY)来进行XXX - YYY的运算.
select datediff(t2.date, t1.date) from t1, t2;

-- 使用date_format(字段名,'%Y-%m-%D')来获得date类型的年、月、日
select date_format(date, '%Y-%m') as month from tb group by(date_format(date, '%Y-%m'));

5. 格式处理

-- 小数位数处理

-- round(XXX, 小数位数) 四舍五入保留指定位数,当小数位数为负数,则开始保留整数位数
select round(t1.temperature, 2) from t1;

-- truncate(XXX, 小数位数) 在指定位数截断小数,舍去后面所有的位数
select truncate(t1.temperature, 2) from t1;

-- format(XXX, 小数位数) 四舍五入保留指定位数,位数不足用0补全,返回格式为字符串
select format(t1.temperature, 2) from t1;

6. 性能

-- in/not in, distinct运算效率较低。可改为存在性判断替代集合运算和去重。

-- 查询所有主管的姓名和职位
select t1.ename, t1.job from tb_emp t1 where exists
(select 'x' from tb_emp t2 where t1.eno = t2.mgr);

-- --------------------------------------------------------------------


-- limit  offset: 当offset 较大时,查询多个字段性能较差。可改为先查主键(带索引性能好),
-- 再根据主键去查多列

select tb_emp.ename, tb_emp.job, tb_emp.sal from tb_emp
where tb_emp.eno = (select tb_emp.eno from tb_emp limit 1 offset 1000000000)

7. 数据库设计

        7.1   1NF:每个字段不能再进行差分。

                例:表中,电话字段又分为固定电话和手机,则不满足1NF

        7.2   2NF:非主键字段由全部主键才能决定。

                例1:主键(学号,学院号),字段 学院名称,则不满足2NF

                        (因为学院号就能决定学院名称)

                例2:单主键,一般都满足2NF

        7.3   3NF:非主键字段不能由其他非主键字段决定。

                例:主键(学号),字段 学院号,学院名称,则不满足3NF

                        (因为学号能决定学院号,而学院号能决定学院名称)

        

        7.4  BNF:有多种主键组合时,所有组合中的每个字段,都必须由其他所有字段才能决定。

                例:主键(仓库号,货物号),属性 货物数量 仓库名,则不满足BNF

                        (因为(仓库名, 货物号)也可以作为主键,而仓库名和仓库号可以相互决定。)

        7.5  不满足BNF及以下时,可能导致的问题:

                7.5.1 冗余性 减慢速度

                7.5.2 更新异常 每次更新属性,需要更新所有记录,否则记录之间产生冲突

                7.5.3 插入异常 因为冗余的字段不能为空

                7.5.4 删除异常 会连带删除冗余的字段

8. pymsql

    cursor.execute(),括号中执行的sql语句只能有一个分号,否则执行失败。

    原因是mysql服务器防止堆叠注入。

9. 索引

-- 创建复合索引
-- 此复合索引能发挥索引性能的情况是:1. 按ename查询 2. 按ename,job查询
-- 只查job时,此索引无法发挥作用,走index扫描。因为job在右侧
create index idx_emp on tb_emp (ename, job)

10. sum、avg、count、max、min窗口函数

如果over()中不写order by,那么窗口函数的对象是partition by生效后的所有记录。

如果over()中什么也不写,那么会返回所有行,每行都有相同的计算结果字段。(而如果不写over,只返回带有计算结果字段的一行)

count()可以附加条件,但一定要加另一情况。比如count(num = 2 or null), count(if(num=2, 1, null))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值