GVKun编程网logo

常量字符串列表中带有INNER JOIN的SQL INSERT(字符串insert方法)

14

在这里,我们将给大家分享关于常量字符串列表中带有INNERJOIN的SQLINSERT的知识,让您更了解字符串insert方法的本质,同时也会涉及到如何更有效地(转载)Mysql----Join用法(

在这里,我们将给大家分享关于常量字符串列表中带有INNER JOIN的SQL INSERT的知识,让您更了解字符串insert方法的本质,同时也会涉及到如何更有效地(转载) Mysql----Join用法(Inner join,Left join,Right join, Cross join, Union模拟Full join)及---性能优化、mysql left join快速转inner join的过程、Mysql必读mysql left join,right join,inner join的区别、MySQL连接查询(inner join,left join和right join的区别)的内容。

本文目录一览:

常量字符串列表中带有INNER JOIN的SQL INSERT(字符串insert方法)

常量字符串列表中带有INNER JOIN的SQL INSERT(字符串insert方法)

我想创建一个SQL Server 2012查询,该查询将一个恒定的权限名称列表插入到表RolePermissions中,例如“
ViewUsersPermission”,“ ModifyUsersPermission”。

该表有两列:“ RoleID”(是Roles表的外键)和varchar列“ PermissionTypeName”。

INSERT INTO [dbo].[RolePermissions] ([PermissionTypeName], [RoleID])   SELECT ''ViewUsersPermission'' AS [PermissionTypeName]   UNION ALL   SELECT ''ModifyUsersPermission'' AS [PermissionTypeName]   UNION ALL   SELECT ''ViewRolesPermission'' AS [PermissionTypeName]   INNER JOIN   (SELECT [RoleID] FROM [dbo].[Roles]                WHERE [Name] = ''Administrator'')

我正在寻找更好的解决方案。我想指定一个权限类型列表,例如:

SELECT FROM ''ViewUsersPermission'', ''ModifyUsersPermission'', ''ViewRolesPermission''

而不是使用UNION ALL构造。

答案1

小编典典

假设您至少在2008年

SELECT RoleNameFROM   (VALUES(''ViewUsersPermission''),              (''ModifyUsersPermission''),              (''ViewRolesPermission'')) V(RoleName)

(转载) Mysql----Join用法(Inner join,Left join,Right join, Cross join, Union模拟Full join)及---性能优化

(转载) Mysql----Join用法(Inner join,Left join,Right join, Cross join, Union模拟Full join)及---性能优化

http://blog.csdn.net/ochangwen/article/details/52346610

 

前期数据准备

CREATE TABLE  atable(
aID int( 1 ) AUTO_INCREMENT PRIMARY KEY ,
aNum char( 20 ));

CREATE TABLE btable(
bID int( 1 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
bName char( 20 ) );

INSERT INTO atable
VALUES ( 1, ''a20050111'' ) , ( 2, ''a20050112'' ) , ( 3, ''a20050113'' ) , ( 4, ''a20050114'' ) , ( 5, ''a20050115'' ) ;

INSERT INTO btable
VALUES ( 1, '' 2006032401'' ) , ( 2, ''2006032402'' ) , ( 3, ''2006032403'' ) , ( 4, ''2006032404'' ) , ( 8, ''2006032408'' ) ;

-------------------------------------------------------------------------------------------

atable:左表;btable:右表。
JOIN 按照功能大致分为如下三类:
  1).inner join(内连接,或等值连接):取得两个表中存在连接匹配关系的记录。
  2).left  join(左连接):取得左表(atable)完全记录,即是右表(btable)并无对应匹配记录。
  3).right join(右连接):与 LEFT JOIN 相反,取得右表(btable)完全记录,即是左表(atable)并无匹配对应记录。
注意:mysql不支持Full join,不过可以通过 union 关键字来合并 left join 与 right join来模拟full join.

一、Inner join

  内连接,也叫等值连接,inner join产生同时符合A和B的一组数据。
  接下来给出一个列子用于解释下面几种分类。如下两个表(A,B)

 
  1. mysql> select * from atable  inner join btable  on atable.aid=btable.bid;  
  2. +-----+-----------+-----+-------------+  
  3. | aID | aNum      | bID | bName       |  
  4. +-----+-----------+-----+-------------+  
  5. |   1 | a20050111 |   1 |  2006032401 |  
  6. |   2 | a20050112 |   2 | 2006032402  |  
  7. |   3 | a20050113 |   3 | 2006032403  |  
  8. |   4 | a20050114 |   4 | 2006032404  |  
  9. +-----+-----------+-----+-------------+  

 

二、Left join

  left join,(或left outer join:在Mysql中两者等价,推荐使用left join.)左连接从左表(A)产生一套完整的记录,与匹配的记录(右表(B)) .如果没有匹配,右侧将包含null。

 

 
  1. mysql> select * from atable  left join btable  on atable.aid=btable.bid;  
  2. +-----+-----------+------+-------------+  
  3. | aID | aNum      | bID  | bName       |  
  4. +-----+-----------+------+-------------+  
  5. |   1 | a20050111 |    1 |  2006032401 |  
  6. |   2 | a20050112 |    2 | 2006032402  |  
  7. |   3 | a20050113 |    3 | 2006032403  |  
  8. |   4 | a20050114 |    4 | 2006032404  |  
  9. |   5 | a20050115 | NULL | NULL        |  
  10. +-----+-----------+------+-------------+  


------------------------------------------------------------------------------------------------------------

 

  2).如果想只从左表(A)中产生一套记录,但不包含右表(B)的记录,可以通过设置where语句来执行,如下

 

 
  1. mysql> select * from atable  left join btable  on atable.aid=btable.bid   
  2.     -> where atable.aid is  null or btable.bid is  null;  
  3. +-----+-----------+------+-------+  
  4. | aID | aNum      | bID  | bName |  
  5. +-----+-----------+------+-------+  
  6. |   5 | a20050115 | NULL | NULL  |  
  7. +-----+-----------+------+-------+  


-----------------------------------------------------------------------------------------

 

同理,还可以模拟inner join. 如下:


 

 
  1. mysql> select * from atable  left join btable  on atable.aid=btable.bid  where atable.aid is not null and btable.bid is not null;  
  2. +-----+-----------+------+-------------+  
  3. | aID | aNum      | bID  | bName       |  
  4. +-----+-----------+------+-------------+  
  5. |   1 | a20050111 |    1 |  2006032401 |  
  6. |   2 | a20050112 |    2 | 2006032402  |  
  7. |   3 | a20050113 |    3 | 2006032403  |  
  8. |   4 | a20050114 |    4 | 2006032404  |  
  9. +-----+-----------+------+-------------+  

------------------------------------------------------------------------------------------

 

三、Right join

  同Left join

 

  1. mysql> select * from atable  right join btable  on atable.aid=btable.bid;  
  2. +------+-----------+-----+-------------+  
  3. | aID  | aNum      | bID | bName       |  
  4. +------+-----------+-----+-------------+  
  5. |    1 | a20050111 |   1 |  2006032401 |  
  6. |    2 | a20050112 |   2 | 2006032402  |  
  7. |    3 | a20050113 |   3 | 2006032403  |  
  8. |    4 | a20050114 |   4 | 2006032404  |  
  9. NULL | NULL      |   8 | 2006032408  |  
  10. +------+-----------+-----+-------------+  

 

四、差集

 

 
  1. mysql> select * from atable  left join btable  on atable.aid=btable.bid    
  2.     -> where btable.bid is null  
  3.     -> union  
  4.     -> select * from atable right join btable on atable.aid=btable.bid  
  5.     -> where atable.aid is null;  
  6. +------+-----------+------+------------+  
  7. | aID  | aNum      | bID  | bName      |  
  8. +------+-----------+------+------------+  
  9. |    5 | a20050115 | NULL | NULL       |  
  10. NULL | NULL      |    8 | 2006032408 |  
  11. +------+-----------+------+------------+  


-----------------------------------------------------------------------------------

 

五.Cross join

  交叉连接,得到的结果是两个表的乘积,即笛卡尔积

    笛卡尔(Descartes)乘积又叫直积。假设集合A={a,b},集合B={0,1,2},则两个集合的笛卡尔积为{(a,0),(a,1),(a,2),(b,0),(b,1), (b,2)}。可以扩展到多个集合的情况。类似的例子有,如果A表示某学校学生的集合,B表示该学校所有课程的集合,则A与B的笛卡尔积表示所有可能的选课情况。

 

 
  1. mysql> select * from atable cross join btable;  
  2. +-----+-----------+-----+-------------+  
  3. | aID | aNum      | bID | bName       |  
  4. +-----+-----------+-----+-------------+  
  5. |   1 | a20050111 |   1 |  2006032401 |  
  6. |   2 | a20050112 |   1 |  2006032401 |  
  7. |   3 | a20050113 |   1 |  2006032401 |  
  8. |   4 | a20050114 |   1 |  2006032401 |  
  9. |   5 | a20050115 |   1 |  2006032401 |  
  10. |   1 | a20050111 |   2 | 2006032402  |  
  11. |   2 | a20050112 |   2 | 2006032402  |  
  12. |   3 | a20050113 |   2 | 2006032402  |  
  13. |   4 | a20050114 |   2 | 2006032402  |  
  14. |   5 | a20050115 |   2 | 2006032402  |  
  15. |   1 | a20050111 |   3 | 2006032403  |  
  16. |   2 | a20050112 |   3 | 2006032403  |  
  17. |   3 | a20050113 |   3 | 2006032403  |  
  18. |   4 | a20050114 |   3 | 2006032403  |  
  19. |   5 | a20050115 |   3 | 2006032403  |  
  20. |   1 | a20050111 |   4 | 2006032404  |  
  21. |   2 | a20050112 |   4 | 2006032404  |  
  22. |   3 | a20050113 |   4 | 2006032404  |  
  23. |   4 | a20050114 |   4 | 2006032404  |  
  24. |   5 | a20050115 |   4 | 2006032404  |  
  25. |   1 | a20050111 |   8 | 2006032408  |  
  26. |   2 | a20050112 |   8 | 2006032408  |  
  27. |   3 | a20050113 |   8 | 2006032408  |  
  28. |   4 | a20050114 |   8 | 2006032408  |  
  29. |   5 | a20050115 |   8 | 2006032408  |  
  30. +-----+-----------+-----+-------------+  
  31. 25 rows in set (0.00 sec)  
  32.   
  33.  <pre><code class="hljs cs"><span class="hljs-function">#再执行:mysql> <span class="hljs-keyword">select</span> * <span class="hljs-keyword">from</span> A inner <span class="hljs-keyword">join</span> B</span>; 试一试 (与上面的结果一样)  
  34.   
  35. <span class="hljs-meta">#在执行mysql> select * from A cross join B on A.name = B.name; 试一试</span></code>  

 

    实际上,在 MySQL 中(仅限于 MySQL) CROSS JOIN 与 INNER JOIN 的表现是一样的,在不指定 ON 条件得到的结果都是笛卡尔积,反之取得两个表完全匹配的结果。    inner join 与 cross join 可以省略 inner 或 cross关键字,因此下面的 SQL 效果是一样的:

 
  1. ... FROM table1 INNER JOIN table2  
  2. ... FROM table1 CROSS JOIN table2  
  3. ... FROM table1 JOIN table2  

 

六.union实现Full join

    全连接产生的所有记录(双方匹配记录)在表A和表B。如果没有匹配,则对面将包含null。与差集类似。

 

 
  1. mysql> select * from atable  left join btable  on atable.aid=btable.bid  
  2.     -> union  
  3.     -> select * from atable right join btable on atable.aid=btable.bid;  
  4. +------+-----------+------+-------------+  
  5. | aID  | aNum      | bID  | bName       |  
  6. +------+-----------+------+-------------+  
  7. |    1 | a20050111 |    1 |  2006032401 |  
  8. |    2 | a20050112 |    2 | 2006032402  |  
  9. |    3 | a20050113 |    3 | 2006032403  |  
  10. |    4 | a20050114 |    4 | 2006032404  |  
  11. |    5 | a20050115 | NULL | NULL        |  
  12. NULL | NULL      |    8 | 2006032408  |  
  13. +------+-----------+------+-------------+  


--------------------------------------------------------------------------------------------------------

 

七.性能优化

  1.显示(explicit) inner join VS 隐式(implicit) inner join

 

 
  1. select * from  
  2. table a inner join table b  
  3. on a.id = b.id;  

VS

 
  1. select a.*, b.*  
  2. from table a, table b  
  3. where a.id = b.id;  

    数据库中比较(10w数据)得之,它们用时几乎相同,第一个是显示的inner join,后一个是隐式的inner join。
2.left join/right join VS inner join
    尽量用inner join.避免 left join 和 null.

 

    在使用left join(或right join)时,应该清楚的知道以下几点:

(1). on与 where的执行顺序
    ON 条件(“A LEFT JOIN B ON 条件表达式”中的ON)用来决定如何从 B 表中检索数据行。如果 B 表中没有任何一行数据匹配 ON 的条件,将会额外生成一行所有列为 NULL 的数据,在匹配阶段 WHERE 子句的条件都不会被使用。仅在匹配阶段完成以后,WHERE 子句条件才会被使用。它将从匹配阶段产生的数据中检索过滤。
    所以我们要注意:在使用Left (right) join的时候,一定要在先给出尽可能多的匹配满足条件,减少Where的执行。如:

 
  1. select * from A  
  2. inner join B on B.name = A.name  
  3. left join C on C.name = B.name  
  4. left join D on D.id = C.id  
  5. where C.status>1 and D.status=1;  

下面这种写法更省时

[sql]  view plain  copy
 
  1. select * from A  
  2. inner join B on B.name = A.name  
  3. left join C on C.name = B.name and C.status>1  
  4. left join D on D.id = C.id and D.status=1  

(2).注意ON 子句和 WHERE 子句的不同

[sql]  view plain  copy
 
  1. mysql> SELECT * FROM product LEFT JOIN product_details  
  2.        ON (product.id = product_details.id)  
  3.        AND product_details.id=2;  
  4. +----+--------+------+--------+-------+  
  5. | id | amount | id   | weight | exist |  
  6. +----+--------+------+--------+-------+  
  7. |  1 |    100 | NULL |   NULL |  NULL |  
  8. |  2 |    200 |    2 |     22 |     0 |  
  9. |  3 |    300 | NULL |   NULL |  NULL |  
  10. |  4 |    400 | NULL |   NULL |  NULL |  
  11. +----+--------+------+--------+-------+  
  12. rows in set (0.00 sec)  
  13.    
  14. mysql> SELECT * FROM product LEFT JOIN product_details  
  15.        ON (product.id = product_details.id)  
  16.        WHERE product_details.id=2;  
  17. +----+--------+----+--------+-------+  
  18. | id | amount | id | weight | exist |  
  19. +----+--------+----+--------+-------+  
  20. |  2 |    200 |  2 |     22 |     0 |  
  21. +----+--------+----+--------+-------+  
  22. 1 row in set (0.01 sec)  

    从上可知,第一条查询使用 ON 条件决定了从 LEFT JOIN的 product_details表中检索符合的所有数据行。第二条查询做了简单的LEFT JOIN,然后使用 WHERE 子句从 LEFT JOIN的数据中过滤掉不符合条件的数据行。
(3).尽量避免子查询,而用join
    往往性能这玩意儿,更多时候体现在数据量比较大的时候,此时,我们应该避免复杂的子查询。如下:

 

 

 
  1. insert into t1(a1) select b1 from t2   
  2. where not exists(select 1 from t1 where t1.id = t2.r_id);  

下面这个更好

 
    1. insert into t1(a1)    
    2. select b1 from t2    
    3. left join (select distinct t1.id from t1 ) t1 on t1.id = t2.r_id     
    4. where t1.id is null;    

mysql left join快速转inner join的过程

mysql left join快速转inner join的过程

在日常优化过程中,发现一个怪事情,同一个SQL出现两个完全不一样执行计划,left join 连驱动表都可以变成不一样。

对于left join,如果where条件里有被关联表过滤,left join有可能被转成inner join ,本案例中shopInfo有ShopCategory = ''LOC''过滤条件; 保证shopInfo的记录非NULL,因此left join在优化过程中可以转为inner join。 那么O和S的JOIN顺序就是可以交换的。

验证结论:

创建表:

--班级表
CREATE TABLE T_CLASS(
  class_id int not null,
  class_name VARCHAR2(100)
);
添加索引
alter table T_CLASS add index inx_class_id(class_id);
--学生表
CREATE TABLE T_STUDENT(
  student_id int not null,
  class_id int not null,
  student_name VARCHAR(100),
  age int,
  sex int 
)
添加索引
alter table T_STUDENT add index index_age(AGE);
--班级数据
insert into T_CLASS (CLASS_ID, CLASS_NAME)
values (1, ''一班'');

insert into T_CLASS (CLASS_ID, CLASS_NAME)
values (2, ''二班'');

insert into T_CLASS (CLASS_ID, CLASS_NAME)
values (3, ''三班'');

insert into T_CLASS (CLASS_ID, CLASS_NAME)
values (4, ''四班'');

insert into T_CLASS (CLASS_ID, CLASS_NAME)
values (5, ''五班'');
--学生数据
insert into T_STUDENT (STUDENT_ID, CLASS_ID, STUDENT_NAME, AGE, SEX)
values (1, 1, ''李1'', 3, ''1'');

insert into T_STUDENT (STUDENT_ID, CLASS_ID, STUDENT_NAME, AGE, SEX)
values (2, 1, ''李2'', 2, ''1'');

insert into T_STUDENT (STUDENT_ID, CLASS_ID, STUDENT_NAME, AGE, SEX)
values (3, 1, ''李3'', 3, ''1'');

insert into T_STUDENT (STUDENT_ID, CLASS_ID, STUDENT_NAME, AGE, SEX)
values (4, 2, ''李4'', 4, ''1'');

insert into T_STUDENT (STUDENT_ID, CLASS_ID, STUDENT_NAME, AGE, SEX)
values (5, 2, ''李5'', 3, ''2'');

insert into T_STUDENT (STUDENT_ID, CLASS_ID, STUDENT_NAME, AGE, SEX)
values (6, 2, ''李6'', 3, ''1'');

insert into T_STUDENT (STUDENT_ID, CLASS_ID, STUDENT_NAME, AGE, SEX)
values (7, 3, ''李7'', 6, ''2'');

insert into T_STUDENT (STUDENT_ID, CLASS_ID, STUDENT_NAME, AGE, SEX)
values (8, 3, ''李8'', 4, ''2'');

insert into T_STUDENT (STUDENT_ID, CLASS_ID, STUDENT_NAME, AGE, SEX)
values (9, 2, ''李9'', 2, ''2'');

insert into T_STUDENT (STUDENT_ID, CLASS_ID, STUDENT_NAME, AGE, SEX)
values (10, 2, ''李10'', 3, ''1'');

insert into T_STUDENT (STUDENT_ID, CLASS_ID, STUDENT_NAME, AGE, SEX)
values (11, 3, ''李11'', 3, ''2'');

insert into T_STUDENT (STUDENT_ID, CLASS_ID, STUDENT_NAME, AGE, SEX)
values (12, 2, ''李12'', 8, ''2'');

insert into T_STUDENT (STUDENT_ID, CLASS_ID, STUDENT_NAME, AGE, SEX)
values (13, 1, ''李13'', 6, ''2'');

案例1:B表有where条件且不为null

案例2: A表和B表均有where条件且不为null

案例3:A表和B表均有where条件且不为null,删除B表索引

结论:

left join 只有被关联表有where条件,且其过滤条件优于关联表的情况下,mysql优化器才转成inner join.

到此这篇关于mysql left join快速转inner join的过程的文章就介绍到这了,更多相关mysql left join inner join内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

您可能感兴趣的文章:
  • 浅谈mysql join底层原理
  • SQL语句中JOIN的用法场景分析
  • MYSQL数据库基础之Join操作原理
  • 解决Mysql的left join无效及使用的注意事项说明
  • 为什么代码规范要求SQL语句不要过多的join
  • mysql高效查询left join和group by(加索引)
  • MySQL的join buffer原理
  • SQL之各种join小结详细讲解

Mysql必读mysql left join,right join,inner join的区别

Mysql必读mysql left join,right join,inner join的区别

《MysqL必读MysqL left join,right join,inner join的区别》要点:
本文介绍了MysqL必读MysqL left join,inner join的区别,希望对您有用。如果有疑问,可以联系我们。

导读:表A记录如下: aID aNum1 a200501112 a200501123 a200501134 a200501145 a20050115表B记录如下: bID bName1 20060324012 2006032402...

表A记录如下:
 MysqL应用

aID aNum
1 a20050111
2 a20050112
3 a20050113
4 a20050114
5 a20050115

表B记录如下:
 MysqL应用

bID bName
1 2006032401
2 2006032402
3 2006032403
4 2006032404
8 2006032408

创建这两个表sql语句如下:
 MysqL应用

CREATE TABLE a
aID int( 1 ) AUTO_INCREMENT PRIMARY KEY,
aNum char( 20 )
)
CREATE TABLE b(
bID int( 1 ) NOT NULL AUTO_INCREMENT PRIMARY KEY,
bName char( 20 )
)MysqL应用

INSERT INTO a
VALUES ( 1,‘a20050111′ ),( 2,‘a20050112′ ),( 3,‘a20050113′ ),( 4,‘a20050114′ ),( 5,‘a20050115′ ) ;MysqL应用

INSERT INTO b
VALUES ( 1,‘ 2006032401′ ),’2006032402′ ),’2006032403′ ),’2006032404′ ),( 8,’2006032408′ ) ;MysqL应用

实验如下:
1.left join(左联接)MysqL应用

sql语句如下:
 MysqL应用

SELECT * FROM a
LEFT JOIN b
ON a.aID =b.bID

结果如下:
aID aNum bID bName
1 a20050111 1 2006032401
2 a20050112 2 2006032402
3 a20050113 3 2006032403
4 a20050114 4 2006032404
5 a20050115 NULL NULL
(所影响的行数为 5 行)MysqL应用

结果说明:
left join是以A表的记录为基础的,A可以看成左表,B可以看成右表,left join是以左表为准的.
换句话说,左表(A)的记录将会全部表示出来,而右表(B)只会显示符合搜索条件的记录(例子中为: A.aID = B.bID).
B表记录不足的地方均为NULL.MysqL应用

2.right join(右联接)MysqL应用

sql语句如下:
 MysqL应用

SELECT * FROM a
RIGHT JOING b
ON a.aID = b.bID

结果如下:
aID aNum bID bName
1 a20050111 1 2006032401
2 a20050112 2 2006032402
3 a20050113 3 2006032403
4 a20050114 4 2006032404
NULL NULL 8 2006032408
(所影响的行数为 5 行)MysqL应用

结果说明:
仔细观察一下,就会发现,和left join的结果刚好相反,这次是以右表(B)为基础的,A表不足的地方用NULL填充.MysqL应用

3.inner join(相等联接或内联接)MysqL应用

sql语句如下:
 MysqL应用

SELECT * FROM a
INNER JOIN b
ON a.aID =b.bID

等同于以下sql句:
 MysqL应用

SELECT *
FROM a,b
WHERE a.aID = b.bID

结果如下:
aID aNum bID bName
1 a20050111 1 2006032401
2 a20050112 2 2006032402
3 a20050113 3 2006032403
4 a20050114 4 2006032404MysqL应用

结果说明:
很明显,这里只显示出了 A.aID = B.bID的记录.这说明inner join并不以谁为基础,它只显示符合条件的记录.
LEFT JOIN操作用于在任何的 FROM 子句中,MysqL应用

组合来源表的记录.使用 LEFT JOIN 运算来创建一个左边外部联接.左边外部联接将包括了从第一个(左边)开始的两个表中的全部记录,即
使在第二个(右边)表中并没有相符值的记录.MysqL应用

语法:FROM table1 LEFT JOIN table2 ON table1.field1 compopr table2.field2
说明:table1,table2参数用于指定要将记录组合的表的名称.
field1,field2参数指定被联接的字段的名称.且这些字段必须有相同的数据类型及包括相同类型的数据,但它们不需要有相同的
名称.
compopr参数指定关系比较运算符:”=”,“<",">“,“<=",">=” 或 “<>“.
如果在INNER JOIN操作中要联接包括Memo 数据类型或 OLE Object 数据类型数据的字段,将会发生错误.MysqL应用

欢迎参与《MysqL必读MysqL left join,inner join的区别》讨论,分享您的想法,小编PHP学院为您提供专业教程。

MySQL连接查询(inner join,left join和right join的区别)

MySQL连接查询(inner join,left join和right join的区别)

关系数据库由多个相关表组成,这些表使用已知为外键列的常用列链接在一起。 因此,从业务角度来看,每个表中的数据是不完整的。

例如,在示例数据库(yiibaidb)中,使用orderNumber列链接的ordersorderdetails表。

ordersorderdetails表的 ER 图如下所示 - 

要获取完整的订单数据,需要从订单(orders)和订单详细(orderdetails)表中查询数据。

这就是为什么要使用连接表了。

MySQL连接是一种基于表之间的公共列的值来链接来自一个(自连接)或更多表的数据的方法。

MySQL支持以下类型的连接:

  • 交叉连接(Cross join)
  • 内连接(Inner join)
  • 左连接(Left join)
  • 右连接(Right join)

要连接表,可以对相应类型的连接使用CROSS JOININNER JOINLEFT JOINRIGHT JOIN子句。 在SELECT语句中的FROM子句之后使用了连接子句。

请注意,MySQL不支持完全外部连接。

为了方便您了解每种类型的连接,我们将使用具有以下结构的两个表:t1t2表:

USE testdb;

CREATE TABLE t1 ( id INT PRIMARY KEY, pattern VARCHAR(50) NOT NULL ); CREATE TABLE t2 ( id VARCHAR(50) PRIMARY KEY, pattern VARCHAR(50) NOT NULL ); 
SQL

t1t2表中都有pattern列,此列也是这两个表之间的公共列。执行以下查询语句将数据插入到t1t2表中:

INSERT INTO t1(id, pattern) VALUES(1,''Divot''), (2,''Brick''), (3,''Grid''); INSERT INTO t2(id, pattern) VALUES(''A'',''Brick''), (''B'',''Grid''), (''C'',''Diamond''); 
SQL

现在两个表中的数据如下所示 - 

2. MySQL交叉连接(CROSS JOIN)

CROSS JOIN生成来自多个表的行的笛卡尔乘积。假设您使用CROSS JOIN来连接t1t2表,结果集将包括t1表中的行与t2表中的行的组合。

要执行交叉连接(最后得到迪卡尔乘积),请使用CROSS JOIN子句,如以下语句所示:

SELECT 
    t1.id, t2.id
FROM t1 CROSS JOIN t2; 
SQL

执行上面语句,得到以下结果 - 

mysql> SELECT 
    t1.id, t2.id FROM t1 CROSS JOIN t2; +----+----+ | id | id | +----+----+ | 1 | A | | 2 | A | | 3 | A | | 1 | B | | 2 | B | | 3 | B | | 1 | C | | 2 | C | | 3 | C | +----+----+ 9 rows in set 
SQL

如您所见,t1表中的每一行与t2表中的行结合形成笛卡尔乘积。

下图显示了t1t2表之间的CROSS JOIN连接 - 

3. MySQL内连接(INNER JOIN)

要形成一个INNER JOIN连接子句,需要一个称为连接谓词的条件。 INNER JOIN需要两个连接的表中的行具有匹配的列值。 INNER JOIN通过组合基于连接谓词的两个连接表的列值来创建结果集。

要连接两个表,INNER JOIN将第一个表中的每一行与第二个表中的每一行进行比较,以找到满足连接谓词的行对。每当通过匹配非NULL值来满足连接谓词时,两个表中每个匹配的行对的列值将包含在结果集中(可以简单地理解为两个表的交集)。

以下语句使用INNER JOIN子句来连接t1t2表:

SELECT 
    t1.id, t2.id
FROM t1 INNER JOIN t2 ON t1.pattern = t2.pattern; 
SQL

在上面语句中,以下表达式是连接谓词:

t1.pattern = t2.pattern
SQL

这意味着t1t2表中的行必须在pattern列中具有相同的值才能包含在结果中。

以下查询的结果可以说明:

+----+----+
| id | id | +----+----+ | 2 | A | | 3 | B | +----+----+ 
SQL

下图显示了t1t2表之间的INNER JOIN

在此图中,两个表中的行必须具有相同pattern列值,才能包含在结果集中。

4. MySQL左连接(LEFT JOIN)

类似于INNER JOINLEFT JOIN也需要连接谓词。当使用LEFT JOIN连接两个表时,介绍了左表和右表的概念。

INNER JOIN不同,LEFT JOIN返回左表中的所有行,包括满足连接谓词的行。 对于不匹配连接谓词的行,右表中的列将使用NULL值显示在结果集中。

以下语句使用LEFT JOIN子句来连接t1t2表:

SELECT 
    t1.id, t2.id
FROM t1 LEFT JOIN t2 ON t1.pattern = t2.pattern ORDER BY t1.id; 
SQL

执行上面查询,得到以下结果 - 

+----+------+
| id | id   | +----+------+ | 1 | NULL | | 2 | A | | 3 | B | +----+------+ 3 rows in set 
SQL

如上所见,t1表中的所有行都包含在结果集中。 对于t2表(右表)中没有任何匹配t1表(左表)中的行,在t2表中的列使用NULL显示。

下图显示了在t1t2表上使用LEFT JOIN子句:

在此图中,以下行具有相同的pattern:(2A),(3B)。 t1表中ID1的行在t2表中没有匹配的行,因此,在结果集中的t2表的列使用NULL代替显示。

5. MySQL右连接(RIGHT JOIN)

右连接(RIGHT JOIN)类似于右连接(LEFT JOIN),除了表的处理是相反的。使用RIGHT JOIN,右表格(t2)中的每一行将显示在结果集中。 对于右表中没有左表(t1)中的匹配行的行,左表(t1)中的列会显示NULL

以下语句使用RIGHT JOIN连接t1t2表:

SELECT 
    t1.id, t2.id
FROM t1 RIGHT JOIN t2 on t1.pattern = t2.pattern ORDER BY t2.id; 
SQL

执行上面是查询语句,得到下面结果 - 

+------+----+
| id   | id |
+------+----+
|    2 | A  |
|    3 | B  |
| NULL | C  |
+------+----+
3 rows in set
Shell

在此结果中,来自右表(t2)的所有行都显示在结果集中。对于左表(t1)中没有匹配右表(t2)中的行,则左表(t1)的列将使用NULL代替显示。

下图显示了t1t2表之间的右连接(RIGHT JOIN):

在本教程中,您已经学习了各种MySQL连接语句,包括交叉连接,内部连接,左连接和右连接,以从两个或多个表查询数据。

今天关于常量字符串列表中带有INNER JOIN的SQL INSERT字符串insert方法的分享就到这里,希望大家有所收获,若想了解更多关于(转载) Mysql----Join用法(Inner join,Left join,Right join, Cross join, Union模拟Full join)及---性能优化、mysql left join快速转inner join的过程、Mysql必读mysql left join,right join,inner join的区别、MySQL连接查询(inner join,left join和right join的区别)等相关知识,可以在本站进行查询。

本文标签: