选择mysql开发的原因_MySQL开发技巧

本文介绍了在MySQL开发中如何进行行列转换,包括行转列的场景与解决方案,以及列转行的实现方法。同时,文章还讨论了如何生成唯一序列号,删除重复数据,以及在子查询中匹配多个条件的问题,提供了实用的SQL示例。
摘要由CSDN通过智能技术生成

如何进行行列转换

行转列

场景:报表统计(sum())、汇总显示

表数据:

select * from score;

bf7aa5ef95eb27f65729b430764a3ce1.png

希望达到的效果

f6b468fb3c10dd22d6ec19f006eabe36.png

cross join

SQL如下:

select a.student_name '学生名', a.score '语文', b.score '数学', c.score '英语' from(select student_name, score from score where course_name='语文') across join(select student_name, score from score where course_name='数学') bcross join(select student_name, score from score where course_name='英语') cwhere a.student_name = b.student_name and b.student_name = c.student_name;

使用case

但是使用case的时候达到的效果不好,如下:

64a68a70540c508521154ef8385e216c.png

SQL如下:

select student_name '学生名',case when course_name = '语文' then score end '语文',case when course_name = '数学' then score end '数学',case when course_name = '英语' then score end '英语'

from score;

解决方案:在case的基础上使用分组,并使用sum()函数,SQL如下:

selectstudent_name,sum(case

when course_name = '语文' thenscoreelse 0

end) '语文',sum(case

when course_name = '数学' thenscoreelse 0

end) '数学',sum(case

when course_name = '英语' thenscoreelse 0

end) '英语'

fromscoregroup by student_name;

列转行

场景:属性拆分

表数据:

select * from interest;

2d15e06d59c92e4fcab431afb5d44dba.png

希望达到的效果

e20e2d181453eda9d87c0bfe37e52c07.png

SQL如下:

--需要使用序列表处理列转行的数据

create tabletb_sequence(

idint primary keyauto_increment

);--取决于逗号分割的数据量,这里兴趣爱好最多的就四个,那就暂时插入4条数据

insert into tb_sequence values(), (), (), ();select student_name '学生名', replace(substr(substring_index(interesting, ',', a.id), char_length(substring_index(interesting, ',', a.id - 1)) + 1), ',', '') '兴趣爱好'

fromtb_sequence across join(select student_name, concat(interesting, ',') interesting, length(interesting) - length(replace(interesting, ',', '')) + 1 size frominterest) bon a.id <= b.size;

场景:多列转行

表数据:

select * from student_dress;

2a54903e2d886f19fe576c7b9a38e975.png

希望达到的效果:

5bb34eab42416f02d51b5b65fec6b2f4.png

union all

SQL如下:

select student_name, 'cap' as '类别', cap '名称' fromstudent_dressunion all

select student_name, 'clothing' as '类别', clothing '名称' fromstudent_dressunion all

select student_name, 'pants' as '类别', pants '名称' fromstudent_dressunion all

select student_name, 'shoe' as '类别', shoe '名称' from student_dress order by student_name;

使用case

希望达到的效果:

a9d84ded1dca18a74e263b8bf3a60d55.png

SQL如下:

select student_name '学生名', coalesce(case when b.id = 1 then cap end,case when b.id = 2 then clothing end,case when b.id = 3 then pants end,case when b.id = 4 then shoe end)'名称' from student_dress a cross join tb_sequence b where b.id <= 4 order by student_name;

希望添加类别上去:

fb77ef7fdd2d1932630fd715a2b80358.png

SQL如下:

select student_name '学生名',case

when b.id = 1 then 'cap'

when b.id = 2 then 'clothing'

when b.id = 3 then 'pants'

when b.id = 4 then 'shoe' end '类别',coalesce(case

when b.id = 1 thencapwhen b.id = 2 thenclothingwhen b.id = 3 thenpantswhen b.id = 4 then shoe end)'名称' from student_dress a cross join tb_sequence b where b.id <= 4 order by student_name;

如何生成唯一序列号

场景:数据库主键、业务序列号如发票号、车票号、订单号等。。。

生成序列号的方法:

MySQL:AUTO_INCREMENT

SQLServer:INDENTIDYTY/SEQUENCE

Oracle:SEQUENCE

PgSQL: SEQUENCE

优先选择系统提供的序列号生成方式

在特殊情况下可以使用SQL方式生成序列号

如何删除重复数据

产生数据重复的原因:

人为原因,如复录入数据,重复提交等。。。

系统原因,由于系统升级或者设计的原因使原来可以重复的数据变为不重复了

如何查询数据是否重复:

利用group by和having从句处理

如何处理重复的数据:

删除重复的数据,对于相同数据保留ID最大的

--创建测试删除重复数据表

CREATE TABLE`test_repeat` (

`id`bigint(20) NOT NULLAUTO_INCREMENT,

`name`varchar(45) NOT NULL,PRIMARY KEY(`id`)

) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;--执行至少两次,这里执行两次即可

insert into test_repeat(name) values('Jef');--查询出的内容为执行的上处插入的条数

select * from test_repeat where name = 'Jef';--1、先把需要删除的数据查出来:

select a.id, a.name from test_repeat a join(select name, count(*) cnt, max(id) maxIdfromtest_repeatgroup by name having cnt > 1) b on a.name = b.name where a.id

delete a from test_repeat a join(select name, count(*) cnt, max(id) maxIdfromtest_repeatgroup by name having cnt > 1) b on a.name = b.name where a.id

select * from test_repeat;

如何在子查询中匹配两个值

常见的子查询使用场景

使用子查询可以避免由于子查询中的数据产生的重复

例子:

查询在超市购买过商品的学生名

select student_name '学生名' from student where student_id in(select student_id from student_shopping);

bf882fd526bec5874f82827713fb5d92.png

实现了去重

但是如果不用子查询,使用内连接

select student_name '学生名' from student s join student_shopping sp on s.student_id = sp.student_id;

这样购买了几件商品就会显示几次

131520de3829e838af6cb850c8cedc1f.png

可以使用distinct去重

select distinct student_name '学生名' from student where student_id in(select student_id from student_shopping);

使用子查询更符合语意,更好理解

查询出每一个学生购物种类最多的日期,并列出学生名,购物日期,购物种类

SQL如下:

select a.student_name '学生名', b.buy_date '购买日期', b.maxNum '购买种类' from student a join (select student_id, max(num) maxNum, buy_date from student_shopping group by student_id) b on a.student_id = b.student_id;

e39d9140a2ffadc1b5b27f6d971e3782.png

多列过滤的使用场景:

MySQL中独有的多列过滤方式

SQL如下,效果跟上图一样:

select a.student_name '学生名', b.buy_date '购买日期', b.num '购买种类' from student a join student_shopping b on a.student_id =

b.student_id where (b.student_id, b.num) in (select student_id, max(num) from student_shopping group by student_id);

如何解决同一属性的多值过滤

什么是同一属性的多值过滤

查询出含有Java技能并且技能等级>3的学生名、技能和技能等级

SQL如下:

select a.student_name '学生名', b.skill_name '技能名称', b.skill_level '技能等级' from student a join student_skill b on a.student_id = b.student_id where b.skill_name = 'Java' and b.skill_level > 3;

82704e6aa361ec017a88135cf5002309.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值