1.准备两个表

表a:

  结构:

mysql> desc a;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| name | varchar(40) | NO | PRI | NULL | |
| age | int(11) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+

  数据

表b:

  结构

mysql> desc b;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| nameB | varchar(40) | YES | | NULL | |
| ageB | int(11) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+

  数据:

2.进行连接查询测试:

(1)交叉连接(笛卡尔积)  cross join

mysql> select * from a,b;  #第一种
+------+------+-------+------+
| name | age | nameB | ageB |
+------+------+-------+------+
| A1 | 1 | B1 | 1 |
| A2 | 2 | B1 | 1 |
| A1 | 1 | B2 | 22 |
| A2 | 2 | B2 | 22 |
+------+------+-------+------+
4 rows in set (0.00 sec) mysql> select * from a cross join b;  #第二种
+------+------+-------+------+
| name | age | nameB | ageB |
+------+------+-------+------+
| A1 | 1 | B1 | 1 |
| A2 | 2 | B1 | 1 |
| A1 | 1 | B2 | 22 |
| A2 | 2 | B2 | 22 |
+------+------+-------+------+
4 rows in set (0.00 sec) mysql> select a.*,b.* from a cross join b;  #第二种的又一个写法
+------+------+-------+------+
| name | age | nameB | ageB |
+------+------+-------+------+
| A1 | 1 | B1 | 1 |
| A2 | 2 | B1 | 1 |
| A1 | 1 | B2 | 22 |
| A2 | 2 | B2 | 22 |
+------+------+-------+------+
4 rows in set (0.00 sec)

 (2)内连接    join 或 inner join(在笛卡尔积的基础上过滤)

  • 显示内连接

(1)不带条件的内连接

mysql> select a.*,b.* from a inner join b on a.age=b.ageb;  #第一种 inner join
+------+------+-------+------+
| name | age | nameB | ageB |
+------+------+-------+------+
| A1 | 1 | B1 | 1 |
+------+------+-------+------+
1 row in set (0.00 sec)
mysql> select a.*,b.* from a join b on a.age=b.ageb;  #第二种  join (默认是inner join)
+------+------+-------+------+
| name | age | nameB | ageB |
+------+------+-------+------+
| A1 | 1 | B1 | 1 |
+------+------+-------+------+
1 row in set (0.00 sec)

三个表的显示内连接:

SELECT
a.*,
b.*,
c.*
FROM exampaper a
INNER JOIN bigquestion b
INNER JOIN exampaperquestion c
ON a.paperId = b.paperId
AND b.bigQuertionId = c.bigQuertionId

四个表的显示内连接:

SELECT
train.trainingSchemaName,
train.majorName,
train.createTime,
tc.*, course.*, type.*
FROM
trainschemeinfo train
JOIN train_course tc ON train.trainingSchemeID = tc.trainningSchemeID
INNER JOIN t_course_base_info course ON tc.courseID = course.courseId
INNER JOIN coursetypeinfo type ON tc.typeNum = type.typeNum
WHERE
tc.trainningSchemeID = '661ecb064b164d1ea133956f89beddb7'

与之等价的隐士内连接:

SELECT
train.trainingSchemaName,
train.majorName,
train.createTime,
tc.*, course.*, type.*
FROM
trainschemeinfo train,
train_course tc,
t_course_base_info course,
coursetypeinfo type
WHERE
train.trainingSchemeID = tc.trainningSchemeID
AND tc.courseID = course.courseId
AND tc.typeNum = type.typeNum
AND tc.trainningSchemeID = '661ecb064b164d1ea133956f89beddb7'

(2)显示内连接带条件

mysql> select a.*,b.* from a join b on a.age=b.ageb having a.name='A1';  #having从查出的数据中挑选满足条件的元祖
+------+------+-------+------+
| name | age | nameB | ageB |
+------+------+-------+------+
| A1 | 1 | B1 | 1 |
+------+------+-------+------+
1 row in set (0.00 sec)
  
mysql> select a.*,b.* from a join b on a.age=b.ageb where a.name='A1';  #where查询满足条件的元素
+------+------+-------+------+
| name | age | nameB | ageB |
+------+------+-------+------+
| A1 | 1 | B1 | 1 |
+------+------+-------+------+
1 row in set (0.00 sec)
  • 隐士内连接:
mysql> select * from a,b where a.age=b.ageb;  
+------+------+-------+------+
| name | age | nameB | ageB |
+------+------+-------+------+
| A1 | 1 | B1 | 1 |
+------+------+-------+------+
1 row in set (0.00 sec) mysql> select * from a,b where a.age=b.ageb and a.name='A1';
+------+------+-------+------+
| name | age | nameB | ageB |
+------+------+-------+------+
| A1 | 1 | B1 | 1 |
+------+------+-------+------+
1 row in set (0.00 sec) mysql> select * from a,b where a.age=b.ageb having a.name='A1';
+------+------+-------+------+
| name | age | nameB | ageB |
+------+------+-------+------+
| A1 | 1 | B1 | 1 |
+------+------+-------+------+
1 row in set (0.00 sec)

  where是从本地磁盘查询满足条件的元素,having是从查出的数据中挑选满足条件的元素。执行权限   where>sum()..聚合函数>having

  

 (3)左外连接:(拿左边的匹配右边的,没有找到右边的为null)

mysql> select * from a left join b on a.age = b.ageb;  #第一种 left join
+------+------+-------+------+
| name | age | nameB | ageB |
+------+------+-------+------+
| A1 | 1 | B1 | 1 |
| A2 | 2 | NULL | NULL |
+------+------+-------+------+
2 rows in set (0.00 sec) mysql> select * from a left outer join b on a.age = b.ageb;  #第二种 left outer join
+------+------+-------+------+
| name | age | nameB | ageB |
+------+------+-------+------+
| A1 | 1 | B1 | 1 |
| A2 | 2 | NULL | NULL |
+------+------+-------+------+
2 rows in set (0.00 sec)

(4)右外连接:(拿右边的匹配左边的,没有找到左边的为null)

mysql> select * from a right join b on a.age = b.ageb;  #第一种  right join
+------+------+-------+------+
| name | age | nameB | ageB |
+------+------+-------+------+
| A1 | 1 | B1 | 1 |
| NULL | NULL | B2 | 22 |
+------+------+-------+------+
2 rows in set (0.00 sec) mysql> select * from a right outer join b on a.age = b.ageb;  #第二种 right outer join
+------+------+-------+------+
| name | age | nameB | ageB |
+------+------+-------+------+
| A1 | 1 | B1 | 1 |
| NULL | NULL | B2 | 22 |
+------+------+-------+------+
2 rows in set (0.00 sec)

3.Union 和 union all  取两个表的并集测试

修改b表,加一条和a表重复的数据

b表数据:

a表数据:

(1)   union:   自动去掉重复元素

mysql> select * from a union select * from b;
+------+------+
| name | age |
+------+------+
| A1 | 1 |
| A2 | 2 |
| B1 | 1 |
| B2 | 22 |
+------+------+
4 rows in set (0.00 sec)

 总结:

union:联合的意思,即把两次或多次查询结果合并起来。
要求:两次查询的列数必须一致
推荐:列的类型可以不一样,但推荐查询的每一列,想对应的类型以一样
可以来自多张表的数据:多次sql语句取出的列名可以不一致,此时以第一个sql语句的列名为准。
如果不同的语句中取出的行,有完全相同(这里表示的是每个列的值都相同),那么union会将相同的行合并,最终只保留一行。也可以这样理解,union会去掉重复的行。
如果不想去掉重复的行,可以使用union all。
如果子句中有order by,limit,需用括号()包起来。推荐放到所有子句之后,即对最终合并的结果来排序或筛选,可以对union之后的数据进行排序和分页等操作。

例如:采用union合并的多个表的数据的SQL

  需求是:为了显示学院、专业、班级树,但是这些信息不在一个月表,而且班级表中有专业编号,专业表中有学院编号。思路就是:分别从三个表中获取数据,然后采用union进行合并数据。

SELECT
classID AS departNum,
className AS departName,
"class" AS departType,
(SELECT
majorID
FROM t_major_base_info
WHERE majorID = class.majorID) AS updepartNum
FROM t_class_base_info class
UNION
SELECT majorID AS departNum,
majorName AS departName,
"major" AS departType,
(SELECT
collegeID FROM t_college_base_info
WHERE collegeID=major.collegeID) AS updepartNum
FROM t_major_base_info major
UNION
SELECT collegeId AS departNum,
collegeName AS departName,
"college" AS departType,
"000" AS updepartNum
FROM t_college_base_info

(2)    union all  保留重复元素

   UNION ALL 命令和 UNION 命令几乎是等效的,不过 UNION ALL 命令会列出所有的值。

mysql> select * from a union all select * from b;
+------+------+
| name | age |
+------+------+
| A1 | 1 |
| A2 | 2 |
| B1 | 1 |
| B2 | 22 |
| A1 | 1 |
+------+------+
5 rows in set (0.00 sec)

  

总结:

  UNION 用于合并两个或多个 SELECT 语句的结果集,并消去表中任何重复行。
  UNION 内部的 SELECT 语句必须拥有相同数量的列,列也必须拥有相似的数据类型。
  同时,每条 SELECT 语句中的列的顺序必须相同.

  默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。
  当 ALL 随 UNION 一起使用时(即 UNION ALL),不消除重复行

注意:

1、UNION 结果集中的列名总是等于第一个 SELECT 语句中的列名
2、UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同

补充:今天在项目种用到了从多个表种查询数据把并且分页,实现过程是将所有表的名字传到dao,然后遍历表名字,一起添加条件(前提是需要查询的列名字相同):

    public List<Map<String, Object>> getAllData(List<String> tableNames) {
List<String> sqls = new ArrayList();
StringBuilder sb = null;
for (String tableName : tableNames) {
sb = new StringBuilder();
sb.append("select id,name from ");
sb.append(tableName);
sb.append(" where 1=1");
sb.append(" and name = 'zhangsan'");
sqls.add(sb.toString());
} String sqlFinally = StringUtils.join(sqls, " union ");
sqlFinally += "order by name limit 5,5";
System.out.println(sqlFinally); /*Session session = getSessionFactory().openSession();
SQLQuery sqlQuery = session.createSQLQuery(sqlFinally);
sqlQuery.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
return sqlQuery.list();*/
return null; }

测试:

    public static void main(String[] args) {
GroupDaoImpl g = new GroupDaoImpl();
List tableNames = new ArrayList();
tableNames.add("t1");
tableNames.add("t2");
tableNames.add("t3");
g.getAllData(tableNames);
}

结果:

select id,name from t1 where 1=1 and name = 'zhangsan' union select id,name from t2 where 1=1 and name = 'zhangsan' union select id,name from t3 where 1=1 and name = 'zhangsan' order by name limit 5,5

【连接查询】mySql多表连接查询与union与union all用法的更多相关文章

  1. 010.简单查询、分组统计查询、多表连接查询(sql实例)

    -------------------------------------day3------------ --添加多行数据:------INSERT [INTO] 表名 [(列的列表)] --SEL ...

  2. MySQL多表连接

    主要分3种:内连接,外连接,交叉连接 其        他:联合连接,自然连接 1.内联接 典型的联接运算,使用像 =  或 <> 之类的比较运算).包括相等联接和自然联接. 内联接使用比 ...

  3. Mysql 多表联合查询效率分析及优化

    1. 多表连接类型 1. 笛卡尔积(交叉连接) 在MySQL中可以为CROSS JOIN或者省略CROSS即JOIN,或者使用','  如: SELECT * FROM table1 CROSS JO ...

  4. 查询mysql 哪些表正在被锁状态

    查询mysql 哪些表正在被锁状态 show OPEN TABLES where In_use > 0; 参考链接:http://zhidao.baidu.com/link?url=tCQ70t ...

  5. 解决Mysql连接池被关闭 ,hibernate尝试连接不能连接的问题。 (默认mysql连接池可以访问的时间为8小时,如果超过8小时没有连接,mysql会自动关闭连接池。系统发布第二天访问链接关闭问题。

    解决Mysql连接池被关闭  ,hibernate尝试连接不能连接的问题. (默认MySQL连接池可以访问的时间为8小时,如果超过8小时没有连接,mysql会自动关闭连接池. 所以系统发布第二天访问会 ...

  6. Mybatis-plus多表关联查询,多表分页查询

    学习plus真的觉得写代码真的越来越舒服了.昨天开始接触吧,只要学会了多表关联查询.plus就能随意搭配使用了. 关于怎么搭建的就自行了去研究了哦.这里直接进入主题. 我用的是springboot+m ...

  7. MySQL开发——【联合查询、多表连接、子查询】

    联合查询 所谓的联合查询就是将满足条件的结果进行拼接在同一张表中. 基本语法: select */字段 from 数据表1 union [all | distinct] select */字段 fro ...

  8. mysql多表连接和子查询

    文章实例的数据表,来自上一篇博客<mysql简单查询>:http://blog.csdn.net/zuiwuyuan/article/details/39349611 MYSQL的多表连接 ...

  9. mysql多表连接查询

    新建两张表: 表1:student  截图如下: 表2:course  截图如下: (此时这样建表只是为了演示连接SQL语句,当然实际开发中我们不会这样建表,实际开发中这两个表会有自己不同的主键.) ...

随机推荐

  1. Delphi 判断一个字符串是否为数字

    //函 数 名: IsDigit//返 回 值: boolean//日       期:2011-03-01//参       数: String//功       能: 判断一个字符串是否为数字// ...

  2. poj3061 Subsequence(尺取)

    Description A sequence of N positive integers (10 < N < 100 000), each of them less than or eq ...

  3. 为什么有时候访问某些加密https网站是不需要证书的? https? ssl?

    根证书是CA颁发给自己的证书, 是信任链的起点 1.所有访问https的网站都是需要证书的. 2.对于某些网站,尤其是证书颁发机构的网站,操作系统自动添加了这些网站访问需要的证书到证书管理器中,所以就 ...

  4. hbase 多个过滤器组合(列表)

    使用FilterList要保证过滤器的顺序需要使用List<Filter> private static void mutilFilterData() throws IOException ...

  5. git<commit和分支>

    commit: 在执行提交命令git commit之前,一定要git add要修改的文件,这样才能将更改的内容更新到本地. 在Git 中提交时,会保存一个提交(commit)对象,它包含一个指向暂存内 ...

  6. mac go2shell 安裝

    配合Finder打开Finder,按住command键,拖动Go2Shell的图标到Finder菜单就可以在Finder快捷打开Go2Shell了

  7. R语言颜色综合运用与色彩方案共享

    R语言颜色综合运用与色彩方案共享 小魔方 EasyCharts 2016-11-21 今天这篇主要讲解R语言颜色综合运用,主要跟大家介绍如何提取那些专业色彩包中的颜色搭配用于在基础绘图系统和高级绘图系 ...

  8. python 生成器和迭代器介绍

    在正式接触生成器之前,我们先来了解一些概念 容器(container) 容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个迭代获取,可以用in.not in关键字判断元素是否包含在容器中. ...

  9. P1850 换教室

    P1850 换教室 现在有一张图, 有 \(v <= 300\) 个节点 你需要从 \(c_{1}\) 到 \(c_{2}\) 到 \(c_{n} (n <= 2000)\) 现在你有 \ ...

  10. 安装MySQL5.7由于 Redistributable导致失败

    今天上午安装MySQL5.7时一直提示 1: Action 10:59:21: INSTALL. 1: 1: MySQL Server 5.7 2: {F08E9C75-A42E-4962-8760- ...