完整的外部连接的作用,例如内部连接,在两个表上有多个条件

发布于 2025-01-25 16:04:17 字数 1081 浏览 4 评论 0原文

我正在尝试在两个表之间进行完整的外部连接 table1 table2 on id> id,teradata中的查询如下。问题在于它的作用就像内联合。

SELECT  *
    FROM Table1 AS a   
    FULL OUTER JOIN Table2 AS b
    ON a.ID = b.ID
    WHERE a.country in ('US','FR')         
        AND a.create_date = '2021-01-01'
        AND b.country IN ('US','DE','BE')
        AND b.create_date = '2021-01-01';

我想要的就是这样:

SELECT * FROM 
(
    SELECT * FROM Table1 as a 
    WHERE a.country in ('US','FR')
        AND a.create_date = '2021-01-01'
) as ax
FULL OUTER JOIN
(
    SELECT * FROM Table2 as b 
    WHERE b.country IN ('US','DE','BE')     
        AND b.create_date = '2021-01-01'
) as bx
ON ax.ID=bx.ID;

我觉得第二个查询不是最好的练习,也许在复杂的情况下效率低下和/或难以阅读。如何修改第一个查询以获取所需的输出?

我知道这是一个基本问题,可能还有许多其他方法可以做到这一点(例如,使用,具有等),但找不到基本说明。将欣赏有关替代解决方案的全面答案,以作为未来参考的指南。

编辑 我的问题与 werf lod with with where strause 是我需要一个条件这两个表。我无法弄清楚将第二个放在哪里条件。

I am trying to have a full outer join between two tables Table1 and Table2 on ID with a query like the following in Teradata. The problem is it acts like inner join.

SELECT  *
    FROM Table1 AS a   
    FULL OUTER JOIN Table2 AS b
    ON a.ID = b.ID
    WHERE a.country in ('US','FR')         
        AND a.create_date = '2021-01-01'
        AND b.country IN ('US','DE','BE')
        AND b.create_date = '2021-01-01';

What I want is something like this:

SELECT * FROM 
(
    SELECT * FROM Table1 as a 
    WHERE a.country in ('US','FR')
        AND a.create_date = '2021-01-01'
) as ax
FULL OUTER JOIN
(
    SELECT * FROM Table2 as b 
    WHERE b.country IN ('US','DE','BE')     
        AND b.create_date = '2021-01-01'
) as bx
ON ax.ID=bx.ID;

I feel like the second query is not best practice, maybe inefficient and/or hard to read in complicated cases. How can I modify the first query to get the desired output?

I know that this is a fundamental problem and probably there are many other ways to do it (e.g. with USING, HAVING etc) but could not find a basic explanation. Would appreciate a comprehensive answer on alternative solutions as a guide for future reference.

EDIT
The difference in my question to Left Join With Where Clause is that I require a condition in both tables. I cannot figure out where to put the second WHERE condition.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

简单爱 2025-02-01 16:04:17

简短答案:子句的属于两组谓词。

SELECT  *
    FROM Table1 AS a   
    FULL OUTER JOIN Table2 AS b
    ON a.ID = b.ID
        AND a.country in ('US','FR')         
        AND a.create_date = '2021-01-01'
        AND b.country IN ('US','DE','BE')
        AND b.create_date = '2021-01-01';

on子句都限制了有资格参加联接(预加入过滤)的行,并指定如何匹配行(JOIN CRITERIAIA)。 <代码>其中子句过滤结果(加入之后)。

通常不太可能的替代方案是修改谓词以免过滤不匹配行,例如,假设在两个表中ID在

SELECT  *
    FROM Table1 AS a   
    FULL OUTER JOIN Table2 AS b
    ON a.ID = b.ID
    WHERE (a.country in ('US','FR')         
        AND a.create_date = '2021-01-01'
        OR a.ID IS NULL)
        AND (b.country IN ('US','DE','BE')
        AND b.create_date = '2021-01-01'
        OR b.ID IS NULL);

逻辑上均不为 on 和,其中以内在加入的方式使用相同的方法,但是在这种情况下,网络结果是相同的(许多数据库(包括Teradata)将生成相同的查询计划Inner> Inner Join放置过滤器谓词的位置)。

The short answer: Both sets of predicates belong in the ON clause.

SELECT  *
    FROM Table1 AS a   
    FULL OUTER JOIN Table2 AS b
    ON a.ID = b.ID
        AND a.country in ('US','FR')         
        AND a.create_date = '2021-01-01'
        AND b.country IN ('US','DE','BE')
        AND b.create_date = '2021-01-01';

The ON clause both limits the rows that are eligible to participate in the join (pre-join filtering) and specifies how to match rows (join criteria). The WHERE clause filters results (after the join).

A generally less-desirable alternative would be to modify the predicates so as not to filter out the non-matching rows, e.g. assuming ID is NOT NULL in both tables

SELECT  *
    FROM Table1 AS a   
    FULL OUTER JOIN Table2 AS b
    ON a.ID = b.ID
    WHERE (a.country in ('US','FR')         
        AND a.create_date = '2021-01-01'
        OR a.ID IS NULL)
        AND (b.country IN ('US','DE','BE')
        AND b.create_date = '2021-01-01'
        OR b.ID IS NULL);

Logically the ON and WHERE work the same way for INNER JOIN but in that case the net result is the same (and many databases including Teradata will generate the same query plan for INNER JOIN regardless of where you put the filter predicates).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文