文章目录

  • 关联查询
  • 合并查询
  • 一、内连接查询(INNER JOIN | ON)
  • 二、三表连接
  • 三、左外连接(LEFT JOIN ON)
  • 3.1 leetcode例题
  • 3.2 on和where的区别
  • 3.3 去重查询
  • 四、右外连接(RIGHT JOIN ON)
  • 五、总结
  • 六、数据类型


关联查询

例题如下

select count(*)
from t_activity a 
join t_user u1 on a.activity_owner = u1.user_id
join t_user u2 on a.activity_create_by = u2.user_id
left join t_user u3 on a.activity_edit_by = u3.user_id
where
a.activity_name like "%Lex%"
and 
u1.u_login_act like "%xx%"

上面的查询代码,查的是某个市场活动,查t_activity表(并设置别名为a,简写)
关联查询t_user表(设置别名为u1),没有on后面的条件,a表中每一行数据都对应user表中的全部数据
联系实际就是一个市场活动表,我想要查这个活动负责人的信息,给a表一个owner列,值与其负责人的user_id相等,方便查询
on后面是过滤这些数据,留下u1表中user_id列与a表中activity_owner(市场活动所有者)列相等的数据
联系实际,也就是不是每一个用户都会去负责市场活动,所以a表要的数据是当前负责人的个人信息
再次过滤,查的是市场活动创建者的个人信息,再次过滤,查的是市场活动编辑者的个人信息,查的是市场活动名字有Lex且这个市场活动负责人的u_login_act包含xx的

合并查询

使用合并查询必须保证合并的两张表个的列数相同,列的数据类型可以不同
比如合并的两张表是两个班级的学生信息表,列名都为id和name
则可以合并这两种表

SELECT * FROM t1 UNION SELECT * FROM t2;

保留重复记录

SELECT * FROM t1 UNION ALL SELECT * FROM t2;

一、内连接查询(INNER JOIN | ON)

SELECT * FROM t_employees
INNER JOIN t_jobs
ON t_employees.`job_id` = t_jobs.`job_id`;

sql server 组合查询 in sql 合并查询_字段

二、三表连接

SELECT * FROM t_employees
INNER JOIN t_departments
ON t_employees.`department_id` = t_departments.`dpID`
INNER JOIN t_jobs
ON t_jobs.`job_address` = t_departments.`dpID`;

三、左外连接(LEFT JOIN ON)

左外连接,是以左表为主表,依次向右匹配,匹配到,返回结果,匹配不到,则返回NULL值填充

SELECT employee_id,first_name,salary,department_id 
FROM t_employees
LEFT JOIN t_departments
ON t_departments.`dpID` = t_employees.`department_id`;

上诉代码查询t_employees表和t_departments表,连接的过程当中用的是左连接,也就是LEFT JOIN,左连接就是以左表为主表去向右表去匹配,匹配到就显示这个完整的结果,如果左表t_employees对应的t_departments表没有结果则显示NULL

3.1 leetcode例题

sql server 组合查询 in sql 合并查询_sql server 组合查询 in_02

解题如下:

sql server 组合查询 in sql 合并查询_mysql_03


sql server 组合查询 in sql 合并查询_字段_04

select p.FirstName,p.LastName,a.City,a.State
from Person p
LEFT JOIN Address a
on p.PersonId = a.PersonId;

一开始我用错了用了where做条件判断

sql server 组合查询 in sql 合并查询_mysql_05

3.2 on和where的区别

on后不管条件是否为真,都显示左边表的记录。
where则过滤掉条件不为真的左边表的记录。

对于非主键字段要进行去重处理
如下:

select a.FirstName,a.LastName,b.City,b.State 
from Person a 
left join 
(select PersonId,City,State,row_number()over(partition by PersonId order by AddressId desc) as nt from Address ) b 
on a.PersonId = b.PersonId 
and b.nt = 1

row_number() over()分组排序功能:
在使用 row_number() over()函数时候,over()里头的分组以及排序的执行晚于 where 、group by、 order by 的执行。

over()里
Partition By 后的字段代表根据哪个字段分组,
Order By 后的字段标识用哪个字段排序
得出的列以nt作为字段名
最后根据on后面的b.nt=1取每个分组的第一个数据。

以下是常用sql关键字的优先级

from > where > group by > having > order by

而partition by应用在以上关键字之后,实际上就是在执行完select之后,在所得结果集之上进行partition
partition by相比较于group by,能够在保留全部数据的基础上,只对其中某些字段做分组排序,而group by则只保留参与分组的字段和聚合函数的结果。

partition by常同row_number() over一起使用
‘’
partition by和group by的区别和对比

3.3 去重查询

ROW_NUMBER() OVER()函数用法详解 (分组排序 例子多)

oracle rownumber over partition by,row_number() over partition by去重复

四、右外连接(RIGHT JOIN ON)

SELECT employee_id,first_name,salary,department_id 
FROM t_employees
RIGHT JOIN t_departments
ON t_departments.`dpID` = t_employees.`department_id`;

五、总结

inner join:2表值都存在
outer join:附表中值可能存在null的情况。
总结:
  ①A inner join B:取交集
  ②A left join B:取A全部,B没有对应的值,则为null
  ③A right join B:取B全部,A没有对应的值,则为null
  ④A full outer join B:取并集,彼此没有对应的值为null
  上述4种的对应条件,在on后填写。

六、数据类型

类型

大小

范围

格式

用途

int

4字节

-2147483648~2147483647

整数

double

8字节

-1.797E+308~-2.22E-308

双精度浮点数

double(M,D)

M表示整数位和小数位的总和,D表示小数位

双精度浮点数

decimal(M,D)

M最大值为65

小数值

DATE

3

1000-01-01/9999-12-31

YYYY-MM-DD

日期值

TIME

3

HH:MM:SS

时间值

YEAR

1

1901/2155

YYYY

年份值

DATETIME

8

1000-01-01 00:00:00/9999-12-31 23:59:59

YYYY-MM-DD HH:MM:SS

日期和时间

char

0~255字符

定长字符串char(10)个字符

VARCHAR

0~65535字节

变长字符串varchar(10)10个字符

BLOB

0~65535字节

二进制形式的长文本数据

TEXT

0~65535字节

长文本