两个表的完全联接,两个表都有条件

Posted

技术标签:

【中文标题】两个表的完全联接,两个表都有条件【英文标题】:Full Join on two tables with criteria on both 【发布时间】:2021-03-26 03:37:41 【问题描述】:

我有两个具有匹配键的表。一些记录存在于两个表上,而另一些记录只存在于一个或另一个上。我一生无法弄清楚的是如何在进行完全外部联接时向两个表添加条件。

表 A(编辑:带标准)

+---------------------------+
| ID, AREA, STATUS, YEAR     |
+----------------------------+
| ID1, AA,  YES,  1980       |
| ID2, BB,  NO,   1990       |
| ID3, CC,  YES,  1950       |
| ID4, DD,  NO,   1900       |

表 B(编辑:带标准)

+--------------------------+
| ID, ZONE, CODE, TIME     |
+--------------------------+
| ID1, FF,  1,  12:00      |
| ID5, HH,  1,  11:11      |
| ID6, II,  1,  13:00      |

希望加入

 +------------------------------------------+
 | ID, AREA, STATUS, YEAR, ZONE, CODE, TIME |
 +------------------------------------------+
 | ID1, AA,  YES,  1980,    FF,  1,   2000  |
 | ID2, BB,  NO,   1990,    n/a, n/a,  n/a  |
 | ID3, CC,  YES,  1950     n/a, n/a,  n/a  |
 | ID4, DD,  NO,   1900     n/a, n/a,  n/a  |
 | ID5, n/a, n/a,  n/a,     HH,  1,   2001  |
 | ID6, n/a, n/a,   n/a,    II,  1,   2000  |

到目前为止,我有以下代码。它为我返回除了 ID5 和 ID6 之外的所有内容,由于某种原因,它不会在表 A 中的 col 为空(n/a)的连接中带来行。

SELECT A.ID, A.AREA, A.STATUS, A.YEAR, B.ID, B.ZONE, B.CODE, B.TIME
FROM TableA A 
FULL JOIN TableB B
ON A.ID = B.ID AND /* criteria for B */ (B.ZONE > XX AND B.CODE >= XX)
WHERE /* criteria for A */ A.YEAR > XXXX

我是否将我的标准放在了不正确的位置?如何进行完全联接,同时对 TableA 和 TableB 应用条件?

【问题讨论】:

mysql 作为标签是否真的相关? MySQL 不支持FULL JOIN 所以这个问题显然与 MySQL 无关。 @大卫 。 . .请仅使用您真正使用的数据库标记您的问题。 【参考方案1】:

为了限制全连接的范围,我建议您使用子查询来使用 where 子句来实现想要的条件,例如:

CREATE TABLE A(
   ID     VARCHAR(8) NOT NULL
  ,AREA   VARCHAR(3) NOT NULL
  ,STATUS VARCHAR(5) NOT NULL
  ,YEAR   INTEGER  NOT NULL
);
INSERT INTO A(ID,AREA,STATUS,YEAR) VALUES ('ID1','AA','YES',1980);
INSERT INTO A(ID,AREA,STATUS,YEAR) VALUES ('ID2','BB','NO',1990);
INSERT INTO A(ID,AREA,STATUS,YEAR) VALUES ('ID3','CC','YES',1950);
INSERT INTO A(ID,AREA,STATUS,YEAR) VALUES ('ID4','DD','NO',1900);
CREATE TABLE B(
   ID   VARCHAR(8) NOT NULL
  ,ZONE VARCHAR(3) NOT NULL
  ,CODE BIT  NOT NULL
  ,TIME VARCHAR(17) NOT NULL
);
INSERT INTO B(ID,ZONE,CODE,TIME) VALUES ('ID1','FF',1,'12:00');
INSERT INTO B(ID,ZONE,CODE,TIME) VALUES ('ID5','HH',1,'11:11');
INSERT INTO B(ID,ZONE,CODE,TIME) VALUES ('ID6','II',1,'13:00');
SELECT A.ID, A.AREA, A.STATUS, A.YEAR, B.ID, B.ZONE, B.CODE, B.TIME
FROM A 
FULL JOIN B
ON A.ID = B.ID
GO
身份证 |面积 |状态 |年份 |身份证 |专区 |代码 |时间 :--- | :--- | :----- | ---: | :--- | :--- | :--- | :---- ID1 |机管局 |是 | 1980 | ID1 |法郎 |真 | 12:00 ID2 | BB |否 | 1990 | | | | ID3 |抄送 |是 | 1950 | | | | ID4 | DD |否 | 1900 | | | | | | | | ID5 | HH |真 | 11:11 | | | | ID6 |二 |真 | 13:00
INSERT INTO A(ID,AREA,STATUS,YEAR) VALUES ('ID10','AA','YES',1940);

INSERT INTO B(ID,ZONE,CODE,TIME) VALUES ('ID6','II',-7,'01:30');
SELECT A.ID, A.AREA, A.STATUS, A.YEAR, B.ID, B.ZONE, B.CODE, B.TIME
FROM (
      select * from A where year > 1940
     ) AS A 
FULL JOIN (
     select * from b where code > 0 or time > '12:00'
     ) B
ON A.ID = B.ID
身份证 |面积 |状态 |年份 |身份证 |专区 |代码 |时间 :--- | :--- | :----- | ---: | :--- | :--- | :--- | :---- ID1 |机管局 |是 | 1980 | ID1 |法郎 |真 | 12:00 | | | | ID5 | HH |真 | 11:11 | | | | ID6 |二 |真 | 13:00 | | | | ID6 |二 |真 | 01:30 ID2 | BB |否 | 1990 | | | | ID3 |抄送 |是 | 1950 | | | |

db小提琴here

【讨论】:

非常感谢保罗!那做了我需要的。对 SQL 来说非常新,但您的示例向我展示了子查询是这里的答案。非常感谢!!! 还要注意样本数据的重要性。我需要结果中不需要的行来演示它是如何工作的。【参考方案2】:

我认为作为您的 Desired Join Table,查询应该在第一个连接条件之后结束。

SELECT A.ID, A.AREA, A.STATUS, A.YEAR, B.ID, B.ZONE, B.CODE, B.TIME
FROM TableA A 
FULL JOIN TableB B
ON A.ID = B.ID

已编辑:

SELECT A.ID, A.AREA, A.STATUS, A.YEAR, B.ID, B.ZONE, B.CODE, B.TIME
FROM (SELECT A.ID, A.AREA, A.STATUS, A.YEAR FROM TableA A WHERE A.YEAR > XXXX) A
FULL JOIN (SELECT B.ID, B.ZONE, B.CODE, B.TIME FROM TableB WHERE B.ZONE > XX AND B.CODE >= XX) B
ON A.ID = B.ID

【讨论】:

我编辑了我的帖子以澄清,TableA 和 TableB 示例已经应用了标准。当我尝试加入时,我会将他们的标准放在哪里?如果没有任何条件,这些表将返回 400K 行。 感谢@Nguyễn!我看到您的代码与上面提供的示例和回答 Paul 相关。如果我的原始帖子不清楚,我深表歉意。感谢您在这里的回答,我非常感谢它如何帮助我学习这种新语言!

以上是关于两个表的完全联接,两个表都有条件的主要内容,如果未能解决你的问题,请参考以下文章

1.JOIN和UNION区别

SQL Server-交叉联接内部联接基础回顾

联接表上的条件比参考上的条件快

SQLSERVER 的联接查询写法

SQL:跨两个层次结构的完全外部联接

在使用 LINQ 的对面到内部联接查询方面需要帮助