A8站源码交易平台 以下内容用hive举例:
简单的SQL
数据
student表
#字段名:s_id s_name s_birth s_sex
01 赵雷 1990-01-01 男
02 钱电 1990-12-21 男
03 孙风 1990-05-20 男
04 李云 1990-08-06 男
05 周梅 1991-12-01 女
06 吴兰 1992-03-01 女
07 郑竹 1989-07-01 女
08 王菊 1990-01-20 女
course表
#字段名:c_id c_course t_id
01 语文 02
02 数学 01
03 英语 03
teacher表
#字段名:t_id t_name
01 张三
02 李四
03 王五
score表
#字段名:s_id c_id s_score
01 01 80
01 02 90
01 03 99
02 01 70
02 02 60
02 03 80
03 01 80
03 02 80
03 03 80
04 01 50
04 02 30
04 03 20
05 01 76
05 02 87
06 01 31
06 03 34
07 02 89
07 03 98
建表 A8站源码交易平台
create table if not exists student(
s_id string comment 'this is primary key',
s_name String,
s_birth String,
s_sex String
)
comment 'this is a table'
row format delimited
fields terminated by ' '
lines terminated by '
'
stored as textfile
;
create table if not exists course(
c_id string comment 'this is primary key',
c_course String,
t_id String
)
comment 'this is a table'
row format delimited
fields terminated by ' '
lines terminated by '
'
stored as textfile
;
create table if not exists teacher(
t_id string comment 'this is primary key',
t_name string
)
comment 'this is a table'
row format delimited
fields terminated by ' '
lines terminated by '
'
stored as textfile
;
create table if not exists score(
s_id string comment 'this is primary key',
c_id string comment 'this is primary key',
s_score string
)
comment 'this is a table'
row format delimited
fields terminated by ' '
lines terminated by '
'
stored as textfile
;
加载数据
load data local inpath '/data/course.txt' overwrite into table course;
load data local inpath '/data/student.txt' overwrite into table student;
load data local inpath '/data/teacher.txt' overwrite into table teacher;
load data local inpath '/data/score.txt' overwrite into table score;
主键
能够仅有确认一行数据,尽管hive中主键的概念没那么首要,可是读写数据的时分仍是依靠主键。
在履行SQL的时分,你要时间知道自己这一步的数据是怎么样的。
只需你知道了主键的字段就能够知道一切主键为这个字段的表的一切信息。
履行次序
在自己写一个sql的时分一定要确认履行次序,许多人写SQL过错是因为履行次序过错。
主键
能够仅有确认一行数据,尽管hive中主键的概念没那么首要,可是读写数据的时分仍是依靠主键。
在履行SQL的时分,你要时间知道自己这一步的数据是怎么样的。
只需你知道了主键的字段就能够知道一切主键为这个字段的表的一切信息。
履行次序
在自己写一个sql的时分一定要确认履行次序,许多人写SQL过错是因为履行次序过错。
from 加载,进行表的查找和加载
on 相关字段
join 相关表
where 过滤
group by 分组
having 过滤
select 查询
distinct 去重
order by 排序
limit 约束输出数量
写SQL
查询"李"姓教师的数量
select count(1) from teacher where t_name like '李%';
关于这种没有衔接其他表的SQL,难的话就首要是聚合函数或许自定义函数,了解hive中的内置函数的具体内容是很必要的,在这里就不逐个赘述了。
查询没学过"张三"教师授课的同学的信息
思路
确认我想要的成果,我需求学生信息,就必须要有学生表的主键s_id
从里往外拆分问题,我需求知道张三教师教的什么课,才能够知道谁没学过他的课
select cid from course join (select tid from teacher where tname='张三') a on course.tid=a.tid
持续,没学过这种课的同学编号
select distinct sid from score join 我第二步现已确认的暂时虚拟表(视图)b on score.cid=b.cid
最终一步,我有学生表的主键之后就能够去结合第一步
select student.* from student left join 我第三步现已确认的暂时虚拟表(视图) c on student.sid=c.sid where c.sid is null;
完结
select student.* from student left join
(select distinct sid from score join
(select cid from course join
(select tid from teacher where tname='张三') a on course.tid=a.tid) b
on score.cid=b.cid) c
on student.sid=c.sid where c.sid is null;
查询和"01"号的A8站源码交易平台同学学习的课程完全相同的其他同学的信息
思路:
确认我想要的成果,我需求学生信息,就必须要有学生表的主键s_id
01号学生学了那些课?(我知道课程编号就能够)
select score.c_id c1 from score where score.s_id = '01'
学01号学生课程的人有哪些?(这个时分我要知道哪些人的课程和他完全相同,我能够让学这些课的人的课程数与01课程学的数量相同,这样我就能够知道和他完全相同的人的s_id了)
仅仅靠衔接算数量持平的话,会呈现数量持平可是其他同学或许比01多学了其他课程,所以要再比较课程总数是否持平。判别持平选用简略的衔接办法。
选用比较好了解的办法去处理这个问题,每个问题的处理办法或许有许多种,咱们能够做出许多测验。
-和01相同课程学生选课状况
select score.s_id,count(1) co from score left join
(select score.c_id c1 from score where score.s_id = '01') b
on score.c_id=b.c1
group by score.s_id
正确的:
select f.s_id,f.co1 co from
(select score.s_id,count(1) co1 from score
join (select score.c_id c1 from score where score.s_id = '01') b
on score.c_id=b.c1 group by score.s_id) f
join (select count(c_id) co2 from score where score.s_id = '01' group by score.s_id) g
on f.co1=g.co2
-01学生选课数量
select count(score.c_id) num from score where score.s_id = '01' group by score.s_id
1
-与01相同的只需求衔接两表
select c.s_id from
(select count(score.c_id) num from score where score.s_id = '01' group by score.s_id) d join
(select f.s_id,f.co1 co from
(select score.s_id,count(1) co1 from score join
(select score.c_id c1 from score where score.s_id = '01') b
on score.c_id=b.c1 group by score.s_id) f join
(select count(c_id) co2 from score where score.s_id = '01' group by score.s_id) g on f.co1=g.co2) c
on d.num=c.co
完结(不想要等于01学生信息的话再去掉即可)A8站源码交易平台
select student.* from student left semi join
(select c.s_id
from (select count(score.c_id) num from score where score.s_id = '01' group by score.s_id) d
join
( select f.s_id,f.co1 co from
(select score.s_id,count(1) co1 from
score
join
(select score.c_id c1 from score where score.s_id = '01') b
on score.c_id=b.c1
group by score.s_id) f
join (select count(c_id) co2 from score where score.s_id = '01' group by score.s_id) g
on f.co1=g.co2) c on d.num=c.co) e
on student.s_id=e.s_id
最终,优化
https://blog.csdn.net/qq_43755771/article/details/90725461
总结
写一些衔接比较多的SQL的时分,就能够选用这种从里到外的办法去写SQL句子,SQL句子并不可怕,可怕的是你没有思路,学会拆分,将复杂问题变成简略的问题。
例如:视图便是使用这种办法来简化SQL句子,让咱们的思路变得明晰,在查询过程中创立虚拟表
这也相似咱们学习过程中很重要的分层思维。A8站源码交易平台
扩展
MVC分层(model=>view=>controller=>service=>dao)
数仓的建模和分层(在完结某项目标时会进行分层)
