Sql 两个表上的完全联接,两个表上都有条件
我有两张带匹配键的桌子。一些记录存在于两个表中,其他记录仅存在于其中一个表中。在我的一生中,我无法弄清楚的是,在进行完全外部联接时,如何向两个表添加条件 表A(编辑:带标准) 表B(编辑:带标准) 所需连接Sql 两个表上的完全联接,两个表上都有条件,sql,oracle,oracle-sqldeveloper,Sql,Oracle,Oracle Sqldeveloper,我有两张带匹配键的桌子。一些记录存在于两个表中,其他记录仅存在于其中一个表中。在我的一生中,我无法弄清楚的是,在进行完全外部联接时,如何向两个表添加条件 表A(编辑:带标准) 表B(编辑:带标准) 所需连接 +------------------------------------------+ | ID, AREA, STATUS, YEAR, ZONE, CODE, TIME | +------------------------------------------+ | ID1,
+------------------------------------------+
| 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中列为null(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?我认为,作为所需的联接表,查询应该在第一个联接条件之后结束
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子句实现所需的条件,例如: ID |区域|状态|年份| ID |区域|代码|时间 :--- | :--- | :----- | ---: | :--- | :--- | :--- | :---- ID1 | AA |是| 1980 | ID1 | FF |正确| 12:00 null | null | null | null | ID5 | HH | True | 11:11 null | null | null | null | ID6 | II | True | 13:00 空|空|空|空| ID6 | II |真| 01:30 ID2 | BB | NO | 1990 | null | null | null | null ID3 | CC | YES | 1950 | null | null | null | null
dbfiddle我编辑我的帖子是为了澄清,表A和表B示例已经应用了标准。当我尝试加入时,我将把他们的标准放在哪里?如果没有任何条件,表将返回400K行。@David这应该适用于您的案例谢谢@NguyễN我看到您的代码与上面提供的示例和答案相关联。如果我原来的帖子不清楚,我表示歉意。谢谢你的回答,我真的很感激它帮助我学习这门新语言!非常感谢你,保罗!这正是我所需要的。对SQL非常陌生,但您的示例向我展示了子查询是如何在这里找到答案的。非常感谢!!!还要注意样本数据的重要性。我需要结果中不需要的行来演示它是如何工作的。MySQL实际上与标记相关吗?MySQL不支持
FULL JOIN
,所以这个问题显然与MySQL无关@大卫。请仅使用您真正使用的数据库标记您的问题。
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
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