【问题标题】:SQL Query Not ExistSQL 查询不存在
【发布时间】:2020-06-21 01:27:12
【问题描述】:

我有 2 张桌子,Main 和 Payments。 Main 是一张交易表,Payments 是一张交易表,其中交易为其他交易支付费用。

Main 有许多字段,例如 Invo、InvoDate 和 Amount。

付款非常简单;它只有 PayInvo 和 DueInvo。 [和一个PK]

我必须弄清楚到 2019 年底还有哪些尚未付款。 我的方法如下。 [Main.Ac1 是帐户。所有应付账款都在 2000 年和 2999 年之间]

SELECT * FROM Main 
WHERE InvoDate BETWEEN #1/1/2019# AND #12/31/2019# 
AND Main.Ac1 BETWEEN 2000 AND 2999 
AND NOT EXISTS 
( 
SELECT * FROM 
Payments INNER JOIN Main ON Payments.PayInvo = Main.Invo 
WHERE Main.InvoDate BETWEEN #1/1/2019# AND #12/31/2019#
);

我预计它只会返回 Main.Ac1 BETWEEN 2000 和 2999 以及相应付款日期不是 2019 年的交易列表,但它什么也没带回来。

【问题讨论】:

    标签: sql ms-access


    【解决方案1】:

    您的问题是NOT EXISTS 子句中的子查询与您的主查询不相关,因此它始终返回结果(只要Payments 中有任何行),因此NOT EXISTS 返回 false 和您没有从查询中获得任何行。您可以通过不将 JOINing 与 Main 关联,而是从外部查询中引用 Main 表来关联子查询:

    SELECT * 
    FROM Main 
    WHERE InvoDate BETWEEN #1/1/2019# AND #12/31/2019# 
      AND Main.Ac1 BETWEEN 2000 AND 2999 
      AND NOT EXISTS 
      ( 
        SELECT *
        FROM Payments
        WHERE Payments.PayInvo = Main.Invo 
      )
    

    请注意,您不需要在子查询中进行日期测试,因为它已被外部查询覆盖。

    【讨论】:

    • 这行得通,但我觉得值得一提的是,我决定在付款表中添加一个“paydate”列。从长远来看,这似乎是一门很好的课程
    • @NickFleetwood 我认为这是一个好主意,因为您经常会收到在您感兴趣的发票日期之外发生的付款。在这种情况下,您可以将 paydate 列上的约束添加到子查询。
    【解决方案2】:

    尼克对您现有查询的问题提供了完美的解释。只是提供一个替代方案,请注意,这也可以使用没有子查询的外连接来完成,例如

    select main.* 
    from 
        main left join payments on main.invo = payments.payinvo
    where
        main.invodate between #1/1/2019# and #12/31/2019# and 
        main.ac1 between 2000 and 2999 and 
        payments.payinvo is null
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-04
      • 1970-01-01
      • 1970-01-01
      • 2020-05-28
      • 2012-09-18
      • 1970-01-01
      • 2013-12-05
      相关资源
      最近更新 更多