扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
left join
成都创新互联主要从事成都网站制作、网站设计、网页设计、企业做网站、公司建网站等业务。立足成都服务汉南,十载网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:18980820575
join
主外键是两种对表的约束。
例如:
学生表student(学号(id),姓名(name),性别(sex))
表内有:1,aa,女
课程表subject(课程编号(id),课程名(name))
表内有:1,语文
成绩表grade(成绩编号(id),学号(stu_id),课程号(sub_id),成绩(grade))
表内有:1,1,1,90
成绩表的学号就是学生表的学号相对应,并且为学生表的主键,这样就称成绩表中的学号是学生表的外键,同理,成绩表中的课程号是课程表的外键。
select * from student as s inner join subject as su on su.stu_id=s.id inner join grade as g on g.sub_id=su.id where 1.
扩展资料:
注意事项
SQL 连接(JOIN) 子句用于把来自两个或多个表的行结合起来,基于这些表之间的共同字段。连接的结果可以在逻辑上看作是由SELECT语句指定的列组成的新表。
左连接与右连接的左右指的是以两张表中的哪一张为基准,它们都是外连接。外连接就好像是为非基准表添加了一行全为空值的万能行,用来与基准表中找不到匹配的行进行匹配。
假设两个没有空值的表进行左连接,左表是基准表,左表的所有行都出现在结果中,右表则可能因为无法与基准表匹配而出现是空值的字段。
不同的 SQL JOIN可以使用的不同的 SQL JOIN 类型:
INNER JOIN:如果表中有至少一个匹配,则返回行
LEFT JOIN:即使右表中没有匹配,也从左表返回所有的行
RIGHT JOIN:即使左表中没有匹配,也从右表返回所有的行
FULL JOIN:只要其中一个表中存在匹配,则返回行(MySQL不支持FULL JOIN)
例如:
mysql select * from access_log;
+-----+---------+-------+------------+
| aid | site_id | count | date |
+-----+---------+-------+------------+
| 1 | 1 | 45 | 2016-05-10 |
| 2 | 3 | 100 | 2016-05-13 |
| 3 | 1 | 230 | 2016-05-14 |
| 4 | 2 | 10 | 2016-05-14 |
| 5 | 5 | 205 | 2016-05-14 |
| 6 | 4 | 13 | 2016-05-15 |
| 7 | 3 | 220 | 2016-05-15 |
| 8 | 5 | 545 | 2016-05-16 |
| 9 | 3 | 201 | 2016-05-17 |
+-----+---------+-------+------------+
9 rows in set
create table node_tree( id int not null auto_increment primary key, node_name varchar(128) not null default '', up_node_id int, node_level char(1) )ENGINE=InnoDB default charset=utf8 collate=utf8_swedish_ci;
insert into node_tree(node_name,up_node_id,node_level) values('jx',null,'1'),('jx.webserver',1,'2'),('jx.webserver.nginx1', 2, '3'), ('jx.logserver', 1, '2');
select
node_tree1.id as 主表ID,
node_tree1.name as 主表名字,
node_tree2.name as 从表名字,
node_tree2.up_id as 从表上级ID
from node_tree1, node_tree2
where node_tree1.name='jx';
select
node_tree1.id as 主表ID,
node_tree1.node_name as 主表名字,
node_tree2.node_name as 从表名字,
node_tree2.up_node_id as 从表上级ID
from node_tree as node_tree1, node_tree as node_tree2
where node_tree1.node_name='jx';
一使用SELECT子句进行多表查询
SELECT 字段名 FROM 表1,表2 … WHERE 表1.字段 = 表2.字段 AND 其它查询条件
SELECT a.id,a.name,a.address,a.date,b.math,b.english,b.chinese FROM tb_demo065_tel AS b,tb_demo065 AS a WHERE a.id=b.id
注:在上面的的代码中,以两张表的id字段信息相同作为条件建立两表关联,但在实际开发中不应该这样使用,最好用主外键约束来实现
二使用表的别名进行多表查询
如:SELECT a.id,a.name,a.address,b.math,b.english,b.chinese FROM tb_demo065 a,tb_demo065_tel b WHERE a.id=b.id AND b.id='$_POST[textid]'
SQL语言中,可以通过两种方式为表指定别名
第一种是通过关键字AS指定,如
SELECT a.id,a.name,a.address,b.math,b.english,b.chinese FROM tb_demo065 AS a,tb_demo065_tel AS b WHERE a.id=b.id
第二种是在表名后直接加表的别名实现
SELECT a.id,a.name,a.address,b.math,b.english,b.chinese FROM tb_demo065 a,tb_demo065_tel b WHERE a.id=b.id
使用表的别名应注意几下几点
(1)别名通常是一个缩短了的表名,用于在连接中引用表中的特定列,如果连接中的多个表中有相同的名称列存在,必须用表名或表的别名限定列名
(2)如果定义了表的别名就不能再使用表名
三合并多个结果集
SQL语言中,可以通过UNION 或 ALL将多个SELECT语句的查询结果合并输出,这两个关键字的使用说明如下:
UNION:利用该关键字可以将多个SELECT 语句的查询结果合并输出,并删除重复行
ALL:利用该关键字可以将多个SELECT 语句的查询结果合并输出,但不会删除重复行
在使用UNION或ALL关键字将多个表合并输出时,查询结果必须具有相同的结构并且数据类型必须兼容,另外使用UNION时两张表的字段数量也必须相同,否则会提示SQL语句有错误。
e.x:SELECT id,name,pwd FROM tb_demo067 UNION SELECT uid,price,date FROM tb_demo067_tel
四简单嵌套查询
子查询:子查询是一个SELECT查询,返回单个值且嵌套在SELECT、INSERT、UPDATE和DELETE语句或其它查询语句中,任何可以使用表达式的地方都可以使用子查询.
SELECT id,name,sex,date FROM tb_demo068 WHERE id in(SELECT id FROM tb_demo068 WHERE id='$_POST[test]')
内连接:把查询结果作为WHERE子句的查询条件即称为内连接
五复杂的嵌套查询
多表之间的嵌套查询可以通过谓词IN实现,语法格式如下:
test_expression[NOT] IN{
subquery
}
参数说明:test_expression指SQL表达式,subquery包含某结果集的子查询
多表嵌套查询的原理:无论是多少张表进行嵌套,表与表之间一定存在某种关联,通过WHERE子句建立此种关联实现查询
六嵌套查询在查询统计中的应用
实现多表查询时,可以同时使用谓词ANY、SOME、ALL,这些谓词被称为定量比较谓词,可以和比较运算符联合使用,判断是否全部返回值都满足搜索条件.SOME和ANY谓词是存在量的,只注重是否有返回值满足搜索条件,这两个谓词的含义相同,可以替换使用;ALL谓词称为通用谓词,它只关心是否有谓词满足搜索要求.
SELECT * FROM tb_demo069_people WHERE uid IN(SELECT deptID FROM tb_demo069_dept WHERE deptName='$_POST[select]')
SELECT a.id,a.name FROM tb_demo067 AS a WHERE id3)
ANY 大于子查询中的某个值
=ANY 大于等于子查询中的某个值
=ANY 小于等于子查询中的某个值
=ANY 等于子查询中的某个值
!=ANY或ANY 不等于子查询中的某个值
ALL 大于子查询中的所有值
=ALL 大于等于子查询中的所有值
=ALL 小于等于子查询中的所有值
=ALL 等于子查询中的所有值
!=ALL或ALL 不等于子查询中的所有值
七.使用子查询作派生的表
在实际项目开发过程中经常用到从一个信息较为完善的表中派生出一个只含有几个关键字段的信息表,通过子查询就可以来实现这一目标,如
SELECT people.name,people.chinese,people.math,people.english FROM (SELECT name,chinese,math,english FROM tb_demo071) AS people
注:子查询应遵循以下规则:
(1)由比较运算符引入的内层子查询只包含一个表达式或列名,在外层语句中的WHERE子句内命名的列必须与内层子查询命名的列兼容
(2)由不可更改的比较运算符引入的子查询(比较运算符后面不跟关键字ANY或ALL)不包括GROUP BY 或 HAVING子句,除非预先确定了成组或单个的值
(3)用EXISTS引入的SELECT列表一般都由*组成,不必指定列名
(4)子查询不能在内部处理其结果
八使用子查询作表达式
SELECT (SELECT AVG(chinese)FROM tb_demo071),(SELECT AVG(english)FROM tb_demo071),(SELECT AVG(math)FROM tb_demo071) FROM tb_demo071
注:在使用子查询时最好为列表项取个别名,这样可以方便用户在使用mysql_fetch_array()函数时为表项赋值,如
SELECT (SELECT AVG(chinese) FROM tb_demo071) AS yuwen ,(SELECT AVG(english) FROM tb_demo071) AS yingyu,(SELECT AVG(math) FROM tb_demo071) AS shuxue FROM tb_demo071
九使用子查询关联数据
SELECT * FROM tb_demo072_student WHERE id=(SELECT id FROM tb_demo072_class WHERE className = '$_POST[text]')
十多表联合查询
利用SQL语句中的UNION,可以将不同表中符合条件的数据信息显示在同一列中。
e.x:SELECT * FROM tb_demo074_student UNION SELECT * FROM tb_demo074_fasten
注:使用UNION时应注意以下两点:
(1)在使用UNION运算符组合的语句中,所有选择列表的表达式数目必须相同,如列名、算术表达式及聚合函数等
(2)在每个查询表中,对应列的数据结构必须一样。
十一对联合后的结果进行排序
为了UNION的运算兼容,要求所有SELECT语句都不能有ORDER BY语句,但有一种情况例外,那就是在最后一个SELECT语句中放置ORDER BY 子句实现结果的最终排序输出。
e.x:SELECT * FROM tb_demo074_student UNION SELECT * FROM tb_demo074_fasten ORDER BY id
使用UNION条件上相对比较苛刻,所以使用此语句时一定要注意两个表项数目和字段类型是否相同
十二条件联合语句
SELECT * FROM tb_demo076_BEIJING GROUP BY name HAVING name='人民邮电出版社' OR name='机械工业出版社' UNION SELECT * FROM tb_demo076_BEIJING GROUP BY name HAVING name '人民邮电出版社' AND name '机械工业再版社' ORDER BY id
上面语句应用了GROUP BY分组语句和HAVING语句实现条件联合查询。其实现目的是先保证将'人民邮电出版社'和'机械工业出版社'始终位于名单最前列,然后再输出其它的出版社
十三简单内连接查询
SELECT filedlist FROM table1 [INNER] JOIN table2 ON table1.column1 = table2.column1
其中,filedlist是要显示的字段,INNER表示表之间的连接方式为内连接,table1.column1=table2.column1用于指明两表间的连接条件,如:
SELECT a.name,a.address,a.date,b.chinese,b.math,b.english FROM tb_demo065 AS a INNER JOIN tb_demo065_tel AS b on a.id=b.id
十四复杂内连接查询
复杂的内连接查询是在基本的内连接查询的基础上再附加一些查询条件,如:
SELECT a.name,a.address,a.date,b.chinese,b.math,b.english FROM tb_demo065 AS a INNER JOIN tb_demo065_tel AS b on a.id=b.id WHERE b.id=(SELECT id FROM tb_demo065 WHERE tb_demo065.name='$_POST[text]')
总之,实现表与表之间的关联的本质是两表之间存在共同的数据项或者相同的数据项,通过WHERE 子句或内连接INNER JOIN … ON 语句将两表连接起来,实现查询
十五使用外连接实现多表联合查询
(1)LEFT OUTER JOIN表示表之间通过左连接方式相互连接,也可简写成LEFT JOIN,它是以左侧的表为基准故称左连接,左侧表中所有信息将被全部输出,而右侧表信息则只会输出符合条件的信息,对不符合条件的信息则返回NULL
e.x:SELECT a.name,a.address,b.math,b.english FROM tb_demo065 AS A LEFT OUTER JOIN tb_demo065_tel AS b ON a.id=b.id
(2)RIGHT OUTER JOIN表示表之间通过右连接方式相互连接,也可简写成RIGHT JOIN,它是以右侧的表为基准故称右连接,右侧表中所有信息将被全部输出,而左侧表信息则只会输出符合条件的信息,对不符合条件的信息则返回NULL
E.X:SELECT a.name,a.address,b.math,b.english FROM tb_demo065 AS A RIGHT OUTER JOIN tb_demo065_tel AS b ON a.id=b.id
十六利用IN或NOTIN关键字限定范围
e.x:SELECT * FROM tb_demo083 WHERE code IN(SELECT code FROM tb_demo083 WHERE code BETWEEN '$_POST[text1]' AND '$_POST[text2]')
利用IN可指定在范围内查询,若要求在某范围外查询可以用NOT IN代替它
十七由IN引入的关联子查询
e.x:SELECT * FROM tb_demo083 WHERE code IN(SELECT code FROM tb_demo083 WHERE code = '$_POST[text]')
十八利用HAVING语句过滤分组数据
HAVING子句用于指定组或聚合的搜索条件,HAVING通常与GROUP BY 语句一起使用,如果SQL语句中不含GROUP BY子句,则HAVING的行为与WHERE子句一样.
e.x:SELECT name,math FROM tb_demo083 GROUP BY id HAVING math '95'
以每24小时作为一份时间(而非自然日),根据用户的配置有两种工作模式:带状模式中,用户仅定义开始日期时,从开始日期(含)开始,每份时间1个分片地无限增加下去;环状模式中,用户定义了开始日期和结束日期时,以结束日期(含)和开始日期(含)之间的时间份数作为分片总数(分片数量固定),以类似取模的方式路由到这些分片里。
1. DBLE 启动时,读取用户在 rule.xml 配置的 sBeginDate 来确定起始时间
2. 读取用户在 rule.xml 配置的 sPartionDay 来确定每个 MySQL 分片承载多少天内的数据
3. 读取用户在 rule.xml 配置的 dateFormat 来确定分片索引的日期格式
4. 在 DBLE 的运行过程中,用户访问使用这个算法的表时,WHERE 子句中的分片索引值(字符串),会被提取出来尝试转换成 Java 内部的时间类型
5. 然后求分片索引值与起始时间的差,除以 MySQL 分片承载的天数,确定所属分片
1. DBLE 启动时,读取用户在 rule.xml 配置的起始时间 sBeginDate、终止时间 sEndDate 和每个 MySQL 分片承载多少天数据 sPartionDay
2. 根据用户设置,建立起以 sBeginDate 开始,每 sPartionDay 天一个分片,直到 sEndDate 为止的一个环,把分片串联串联起来
3. 读取用户在 rule.xml 配置的 defaultNode
4. 在 DBLE 的运行过程中,用户访问使用这个算法的表时,WHERE 子句中的分片索引值(字符串),会被提取出来尝试转换成 Java 内部的日期类型
5. 然后求分片索引值与起始日期的差:如果分片索引值不早于 sBeginDate(哪怕晚于 sEndDate),就以 MySQL 分片承载的天数为模数,对分片索引值求模得到所属分片;如果分片索引值早于 sBeginDate,就会被放到 defaultNode 分片上
与MyCat的类似分片算法对比
中间件
DBLE
MyCat
分片算法种类 date 分区算法 按日期(天)分片
两种中间件的取模范围分片算法使用上无差别
开发注意点
【分片索引】1. 必须是字符串,而且 java.text.SimpleDateFormat 能基于用户指定的 dateFormat 来转换成 java.util.Date
【分片索引】2. 提供带状模式和环状模式两种模式
【分片索引】3. 带状模式以 sBeginDate(含)起,以 86400000 毫秒(24 小时整)为一份,每 sPartionDay 份为一个分片,理论上分片数量可以无限增长,但是出现 sBeginDate 之前的数据而且没有设定 defaultNode 的话,会路由失败(如果有 defaultNode,则路由至 defaultNode)
【分片索引】4. 环状模式以 86400000 毫秒(24 小时整)为一份,每 sPartionDay 份为一个分片,以 sBeginDate(含)到 sEndDate(含)的时间长度除以单个分片长度得到恒定的分片数量,但是出现 sBeginDate 之前的数据而且没有设定 defaultNode 的话,会路由失败(如果有 defaultNode,则路由至 defaultNode)
【分片索引】5. 无论哪种模式,分片索引字段的格式化字符串 dateFormat 由用户指定
【分片索引】6. 无论哪种模式,划分不是以日历时间为准,无法对应自然月和自然年,且会受闰秒问题影响
运维注意点
【扩容】1. 带状模式中,随着 sBeginDate 之后的数据出现,分片数量的增加无需再平衡
【扩容】2. 带状模式没有自动增添分片的能力,需要运维手工提前增加分片;如果路由策略计算出的分片并不存在时,会导致失败
【扩容】3. 环状模式中,如果新旧 [sBeginDate,sEndDate] 之间有重叠,需要进行部分数据迁移;如果新旧 [sBeginDate,sEndDate] 之间没有重叠,需要数据再平衡
配置注意点
【配置项】1. 在 rule.xml 中,可配置项为 propertyname="sBeginDate" 、 propertyname="sPartionDay" 、 propertyname="dateFormat" 、 propertyname="sEndDate" 和 propertyname="defaultNode"
【配置项】2.在 rule.xml 中配置 propertyname="dateFormat",符合 java.text.SimpleDateFormat 规范的字符串,用于告知 DBLE 如何解析sBeginDate和sEndDate
【配置项】3.在 rule.xml 中配置 propertyname="sBeginDate",必须是符合 dateFormat 的日期字符串
【配置项】4.在 rule.xml 中配置 propertyname="sEndDate",必须是符合 dateFormat 的日期字符串;配置了该项使用的是环状模式,若没有配置该项则使用的是带状模式
【配置项】5.在 rule.xml 中配置 propertyname="sPartionDay",非负整数,该分片策略以 86400000 毫秒(24 小时整)作为一份,而 sPartionDay 告诉 DBLE 把每多少份放在同一个分片
【配置项】6.在 rule.xml 中配置 propertyname="defaultNode" 标签,非必须配置项,不配置该项的话,用户的分片索引值没落在 mapFile 定义
来自MySQL的学习笔记,写的不对的地方大家多多指教哦
什么是外键?
假设有 2 个表,分别是表 A 和表 B,它们通过一个公共字段“id”发生关联关系,我们把这个关联关系叫做 R。如果“id”在表 A 中是主键,那么,表 A 就是这个关系 R 中的主表。相应的,表 B 就是这个关系中的从表,表 B 中的“id”,就是表 B 用来引用表 A 中数据的,叫外键。所以,外键就是从表中用来引用主表中数据的那个公共字段。
语法结构:
在创建表时添加外键约束:
在修改表时定义外键约束:
例子1:创建表时添加外键约束
首先创建主表:importhead
创建从表:test_mysql.importdetails
查询外键约束的相关信息:
查询结果为:
例子2:修改表时定义外键约束
修改表时定义从表test_mysql.importdetails的外键约束
删除外键约束使用DROP,语法结构为:
例子:删除从表test_mysql.importdetails的外键约束
在 MySQL 中,有 2 种类型的连接,分别是内连接(INNER JOIN)和外连接(OUTER JOIN)。
在 MySQL 里面,关键字 JOIN、INNER JOIN、CROSS JOIN 的含义是一样的,都表示内连接。我们可以通过 JOIN 把两个表关联起来,来查询两个表中的数据。
例子:有一张销售表,如下图:
有一张会员信息表,如下图:
通过内连接,查询会员的销售记录:
运行语句,结果如下:
根据上面的结果,其实可以得知:内连接查询到结果集为两个表的交集部分。
跟内连接只返回符合连接条件的记录不同的是,外连接还可以返回表中的所有记录,它包括两类,分别是左连接和右连接。
例子1:左外连接
如果需要查询所有销售记录,则可以使用左外连接
运行语句,结果为:
从上面的结果可以得知,LEFT JOIN左边的表会返回全部记录,而右边的表只返回符合连接条件的记录
例子2:右外连接:
运行语句,结果为:
从上面的结果可以得知,RIGHT JOIN右边的表会返回全部记录,而左边的表只返回符合连接条件的记录
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流