Full Join 在两个表上都有标准

Full Join on two tables with criteria on both

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

Table A(编辑:有标准)

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

Table 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 之外的所有内容,出于某种原因,它不会在 Table 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?

我认为作为您的 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

为了限制全连接的范围,我建议您使用子查询来使用 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
ID   | AREA | STATUS | YEAR | ID   | ZONE | CODE | TIME 
:--- | :--- | :----- | ---: | :--- | :--- | :--- | :----
ID1  | AA   | YES    | 1980 | ID1  | FF   | True | 12:00
ID2  | BB   | NO     | 1990 | null | null | null | null 
ID3  | CC   | YES    | 1950 | null | null | null | null 
ID4  | DD   | NO     | 1900 | null | null | null | null 
null | null | null   | null | ID5  | HH   | True | 11:11
null | null | null   | null | ID6  | II   | True | 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
ID   | AREA | STATUS | YEAR | ID   | ZONE | CODE | TIME 
:--- | :--- | :----- | ---: | :--- | :--- | :--- | :----
ID1  | AA   | YES    | 1980 | ID1  | FF   | True | 12:00
null | null | null   | null | ID5  | HH   | True | 11:11
null | null | null   | null | ID6  | II   | True | 13:00
null | null | null   | null | ID6  | II   | True | 01:30
ID2  | BB   | NO     | 1990 | null | null | null | null 
ID3  | CC   | YES    | 1950 | null | null | null | null 

db<>fiddle here