搞明白mysql的jion,union

来源:互联网 发布:农业国家数据库查询 编辑:程序博客网 时间:2024/05/19 19:32

  • UNION
    • 准备数据
    • 说明
      • union
      • union all
  • JION
    • 数据准备
    • 左联接
    • 右联接
    • 内联接
    • 联接查询参数
    • 效率分析
    • 索引查询和添加

UNION

UNION 操作符用于合并两个或多个 SELECT 语句的结果集。
请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同

准备数据

CREATE table IF NOT exists Employees_China(E_ID INT(2) auto_increment primary KEY NOT NULL,E_NAME CHAR(19) NOT NULL);CREATE table IF NOT exists Employees_USA(E_ID INT(2) auto_increment primary KEY NOT NULL,E_NAME CHAR(20) NOT NULL);INSERT INTO Employees_China VALUES (01, 'Zhang, Hua' ) , ( 02, 'Wang, Wei' ) , ( 03, 'Carter, Thomas' ) , ( 04, 'Yang, Ming' ); INSERT INTO Employees_USA VALUES (01, 'Adams, John' ) , ( 02, 'Bush, George' ) , ( 03, 'Carter, Thomas' ) , ( 04, 'Gates, Bill' ); 

注意这里的e_name长度限制并不一致,但是并不影响union操作,因为只要类型相似就行

说明

SELECT E_Name FROM Employees_China UNION SELECT E_Name FROM Employees_USA;

union

把两个表的数据联接成了一个表,并去掉了重复的数据
Zhang, Hua
Wang, Wei
Carter, Thomas
Yang, Ming
Adams, John
Bush, George
Gates, Bill

SELECT E_Name FROM Employees_China UNION ALL SELECT E_Name FROM Employees_USA;

union all

它不会去掉重复的数据
Zhang, Hua
Wang, Wei
Carter, Thomas
Yang, Ming
Adams, John
Bush, George
Carter, Thomas
Gates, Bill

注:union all虽然不去掉重复的数据,但是它在性能上是有优势的,引文UNION在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果。实际大部分应用中是不会产生重复的记录。

JION

union主要是纵向联接,而jion是横向联接,把多个表的列合并到一张表当中。注:CROSS JION 暂时与 Inner jion一样

数据准备

create table if not exists a( id int(1) auto_increment not null primary key, num char(20) not null);create table if not exists b( id int(1) auto_increment not null primary key, name char(20) not null);INSERT INTO A  VALUES ( 1, 'a20050111' ) , ( 2, 'a20050112' ) , ( 3, 'a20050113' ) , ( 4, 'a20050114' ) , ( 5, 'a20050115' ) ; INSERT INTO B VALUES ( 1, ' 2006032401' ) , ( 2, '2006032402' ) , ( 3, '2006032403' ) , ( 4, '2006032404' ) , ( 8, '2006032408' ) ;

左联接

说明:像左表(A)看齐,左表(A)的记录将会全部表示出来,而右表(B)只会显示符合搜索条件的记录(a.id=b.id),b表记录不足的直接补null

SELECT * FROM a LEFT JOIN  b  ON A.ID = B.ID;

1 a20050111 1 2006032401
2 a20050112 2 2006032402
3 a20050113 3 2006032403
4 a20050114 4 2006032404
5 a20050115 null null

右联接

说明:像右表(B)看齐,左表A记录不足的补null
1 a20050111 1 2006032401
2 a20050112 2 2006032402
3 a20050113 3 2006032403
4 a20050114 4 2006032404
null null 8 2006032408

内联接

说明:内连接相当于下面的查询语句,不以哪个表作为标准,仅仅列出符合要求的列

SELECT *  FROM a,b WHERE a.ID = b.ID;
SELECT * FROM  a INNER JOIN  b ON a.ID =b.ID;

1 a20050111 1 2006032401
2 a20050112 2 2006032402
3 a20050113 3 2006032403
4 a20050114 4 2006032404

联接查询参数

这部分内容原始地址:http://blog.csdn.net/timecolor/article/details/8739812
1.USING (column_list):其作用是为了方便书写联结的多对应关系,大部分情况下USING语句可以用ON语句来代替,如下面例子:

a LEFT JOIN b USING (c1,c2,c3),其作用相当于下面语句
a LEFT JOIN b ON a.c1=b.c1 AND a.c2=b.c2 AND a.c3=b.c3

只是用ON来代替会书写比较麻烦而已。

2.NATURAL [LEFT] JOIN:这个句子的作用相当于INNER JOIN,或者是在USING子句中包含了联结的表中所有字段的Left JOIN(左联结)。

3.STRAIGHT_JOIN:由于默认情况下MySQL在进行表的联结的时候会先读入左表,当使用了这个参数后MySQL将会先读入右表,这是个MySQL的内置优化参数,大家应该在特定情况下使用,譬如已经确认右表中的记录数量少,在筛选后能大大提高查询速度。

最后要说的就是,在MySQL5.0以后,运算顺序得到了重视,所以对多表的联结查询可能会错误以子联结查询的方式进行。譬如你需要进行多表联结,因此你输入了下面的联结查询:

SELECT t1.id,t2.id,t3.id
FROM t1,t2
LEFT JOIN t3 ON (t3.id=t1.id)
WHERE t1.id=t2.id;

但是MySQL并不是这样执行的,其后台的真正执行方式是下面的语句:

SELECT t1.id,t2.id,t3.id
FROM t1,( t2 LEFT JOIN t3 ON (t3.id=t1.id) )
WHERE t1.id=t2.id;

这并不是我们想要的效果,所以我们需要这样输入:

SELECT t1.id,t2.id,t3.id
FROM (t1,t2)
LEFT JOIN t3 ON (t3.id=t1.id)
WHERE t1.id=t2.id;

效率分析

说明,在join查询时,如果使用相当类型的列和建立了索引,会大的提高查询效率;
另外一篇讲解jion效率的博客:点击这里

索引查询和添加

显示a表索引
SHOW INDEX FROM A;

显示database_test数据库下面所有的索引
SELECT DISTINCT TABLE_NAME,INDEX_NAME FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA = ‘database_test’;

显示整个mysql的索引
use information_schema;
SELECT * FROM statistics;

建立索引有几种方式
创建简单索引
CREATE INDEX index_name ON table_name (column_name)
注:别忘记列名的括号,此时的索引是可以重复的

创建唯一索引
CREATE UNIQUE INDEX index_name
ON table_name (column_name)

改变现有列为索引列
ALTER TABLE table_name ADD INDEX second_index (column_name);

创建表时加索引
[index_type] [index_name] (index_col_name,…)

CREATE table IF NOT exists Employees_Tester(E_ID INT(2) auto_increment primary KEY NOT NULL,E_NAME CHAR(19) NOT NULL ,unique index my_index (e_name));

参考资料:
http://www.phpstudy.net/e/sql/sql_join.html
http://blog.csdn.net/timecolor/article/details/8739812
http://blog.csdn.net/hguisu/article/details/5731880
http://blog.sina.com.cn/s/blog_459208190100qy3z.html

0 0
原创粉丝点击