MySQL开发技巧1 MySQL基础表和数据

MySQL基础表和数据

如何进行行列转换

行转列

场景:报表统计(sum())、汇总显示
表数据:
select * from score;

希望达到的效果

 

cross join

SQL如下:

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

使用case

但是使用case的时候达到的效果不好,希望知道的告知一下,如下:

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;

列转行

场景:属性拆分
表数据:
select * from interest;

希望达到的效果

SQL如下:

-- 需要使用序列表处理列转行的数据
create table tb_sequence(
id int primary key auto_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), ',', '') '兴趣爱好' 
from tb_sequence a 
cross join 
(select student_name, concat(interesting, ',') interesting, length(interesting) - length(replace(interesting, ',', '')) + 1 size from interest) b 
on a.id <= b.size;

场景:多列转行
表数据:
select * from student_info;

希望达到的效果:

union all

SQL如下:

select student_name, 'cap' as '类别', cap '名称' from student_info
union all
select student_name, 'clothing' as '类别', clothing '名称' from student_info
union all
select student_name, 'pants' as '类别', pants '名称' from student_info
union all
select student_name, 'shoe' as '类别', shoe '名称' from student_info order by student_name;

使用case

希望达到的效果:

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_info a cross join tb_sequence b where b.id <= 4 order by student_name;

希望添加类别上去:

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 then cap
when b.id = 2 then clothing
when b.id = 3 then pants
when b.id = 4 then shoe end
) '名称' from student_info 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 NULL AUTO_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) maxId 
from test_repeat
group by name having cnt > 1) b on a.name = b.name where a.id < b.maxId;

-- 拷贝上处语句,查询改为删除即可
delete a from test_repeat a join (
select name, count(*) cnt, max(id) maxId 
from test_repeat
group by name having cnt > 1) b on a.name = b.name where a.id < b.maxId;

-- 再次执行1处的SQL(所有情况),发现没有需要删除的数据了,或者执行查询全部的SQL(数据量少的情况下使用)
select * from test_repeat;

猜你喜欢

转载自www.cnblogs.com/tufujie/p/8994554.html
今日推荐