数据库的join查询

本文详细介绍了SQL中的不同连接类型,包括内连接、全外连接、左外连接等,并通过实例展示了每种连接产生的结果集特点。此外,还特别提到了交叉连接的概念及其可能带来的性能问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

假设我们有两张表。

  • Table A 是左边的表。
  • Table B 是右边的表。

其各有四条记录,其中有两条记录是相同的,如下所示:

id name       id  name
-- ----       --  ----
1  Pirate     1   Rutabaga
2  Monkey     2   Pirate
3  Ninja      3   Darth Vader
4  Spaghetti  4   Ninja

下面让我们来看看不同的Join会产生什么样的结果。

note: left outer join是左外连接,left outer join也可以写成left join,因为join默认是outer属性的。

 

SELECT * FROM TableA
INNER JOIN TableB
ON TableA.name = TableB.name

id  name       id   name
--  ----       --   ----
1   Pirate     2    Pirate
3   Ninja      4    Ninja

Inner join
产生的结果集中,是A和B的交集。

Venn diagram of SQL inner join
SELECT * FROM TableA
FULL OUTER JOIN TableB
ON TableA.name = TableB.name

id    name       id    name
--    ----       --    ----
1     Pirate     2     Pirate
2     Monkey     null  null
3     Ninja      4     Ninja
4     Spaghetti  null  null
null  null       1     Rutabaga
null  null       3     Darth Vader

Full outer join 产生A和B的并集。但是需要注意的是,对于没有匹配的记录,则会以null做为值。

Venn diagram of SQL cartesian join
SELECT * FROM TableA
LEFT OUTER JOIN TableB
ON TableA.name = TableB.name

id  name       id    name
--  ----       --    ----
1   Pirate     2     Pirate
2   Monkey     null  null
3   Ninja      4     Ninja
4   Spaghetti  null  null

Left outer join 产生表A的完全集,而B表中匹配的则有值,没有匹配的则以null值取代。

Venn diagram of SQL left join
SELECT * FROM TableA
LEFT OUTER JOIN TableB
ON TableA.name = TableB.name
WHERE TableB.id IS null 

id  name       id     name
--  ----       --     ----
2   Monkey     null   null
4   Spaghetti  null   null

产生在A表中有而在B表中没有的集合。

join-left-outer.png
SELECT * FROM TableA
FULL OUTER JOIN TableB
ON TableA.name = TableB.name
WHERE TableA.id IS null
OR TableB.id IS null

id    name       id    name
--    ----       --    ----
2     Monkey     null  null
4     Spaghetti  null  null
null  null       1     Rutabaga
null  null       3     Darth Vader

产生A表和B表都没有出现的数据集。

join-outer.png

还需要注册的是我们还有一个是“交差集” cross join, 这种Join没有办法用文式图表示,因为其就是把表A和表B的数据进行一个N*M的组合,即笛卡尔积。表达式如下:

SELECT * FROM TableA
CROSS JOIN TableB

这个笛卡尔乘积会产生 4 x 4 = 16 条记录,一般来说,我们很少用到这个语法。但是我们得小心,如果不是使用嵌套的select语句,一般系统都会产生笛卡尔乘积然再做过滤。这是对于性能来说是非常危险的,尤其是表很大的时候。

 

 

转载于:https://www.cnblogs.com/pjlhf/p/8675074.html

Fork/Join框架在Java中主要用于并行执行任务,而不是直接用于查询数据库。然而,你可以使用Fork/Join框架来并行执行多个数据库查询任务,并将它们的结果汇总起来。下面是一个示例代码,展示了如何使用Fork/Join框架并行查询数据库: ```java import java.util.ArrayList; import java.util.List; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.RecursiveTask; public class DatabaseQueryTask extends RecursiveTask<List<String>> { private List<String> databases; public DatabaseQueryTask(List<String> databases) { this.databases = databases; } @Override protected List<String> compute() { if (databases.size() <= 1) { // 如果只有一个数据库,直接查询并返回结果 return queryDatabase(databases.get(0)); } else { // 将任务切分成更小的子任务 int mid = databases.size() / 2; DatabaseQueryTask leftTask = new DatabaseQueryTask(databases.subList(0, mid)); DatabaseQueryTask rightTask = new DatabaseQueryTask(databases.subList(mid, databases.size())); // 并行执行子任务 leftTask.fork(); rightTask.fork(); // 合并子任务的结果 List<String> leftResult = leftTask.join(); List<String> rightResult = rightTask.join(); leftResult.addAll(rightResult); return leftResult; } } private List<String> queryDatabase(String database) { // 执行数据库查询操作,并返回结果 // 这里只是一个示例,你需要根据具体的数据库类型和查询语句来实现查询操作 List<String> result = new ArrayList<>(); // 执行数据库查询操作... return result; } public static void main(String[] args) { List<String> databases = new ArrayList<>(); databases.add("database1"); databases.add("database2"); databases.add("database3"); ForkJoinPool forkJoinPool = new ForkJoinPool(); DatabaseQueryTask task = new DatabaseQueryTask(databases); List<String> result = forkJoinPool.invoke(task); // 处理查询结果 for (String data : result) { System.out.println(data); } } } ``` 在上面的示例中,我们创建了一个`DatabaseQueryTask`类,继承自`RecursiveTask`,并重写了`compute()`方法来执行数据库查询任务。如果数据库数量大于1,我们将任务切分成更小的子任务,并使用`fork()`方法并行执行子任务。最后,我们使用`join()`方法合并子任务的结果,并返回最终的查询结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值