【问题标题】:Access SQL statement: if no entries are valid, return the last oneAccess SQL 语句:如果没有有效的条目,则返回最后一个
【发布时间】:2019-02-22 22:35:26
【问题描述】:

我正在尝试获取解决以下问题的 SQL 语句。

我有一个表“日历”,其中仅包含一列“日期”。该表有 2019 年每个月的 12 个条目(01.31.2019、02.28.2019 等)。第二个表“值”(我从 ERP 系统获得)有三列,“从”、“到”和“金额”(例如 01.01.2019、06.30.2019、50 和 08.01.2019、08.31.2019, 100)。

我有一个简单的语句来检查哪个条目在特定日期有效:

SELECT Calendar.Date, Values.From, Values.To, Values.Amount
FROM Calendar, [Values]
WHERE Calendar.Date >= Values.From 
  AND Calendar.Date <= Values.To;

7 月、9 月、10 月、11 月和 12 月没有有效的条目(在“值”表中)。

如果没有有效条目,则应使用最后一个条目。 7 月份是 50,而 9 月、10 月......它将是 100。

我尝试了子查询和左连接,但我从来没有得到想要的结果。

有没有人对此问题有想法或更好的解决方案。感谢您的支持

【问题讨论】:

标签: sql ms-access left-join


【解决方案1】:

我认为您正在寻找Values 表上的附加连接,它将返回当前日期之前的最后一个条目。当第一个(LEFT) JOIN不成功时,可以使用第二个返回的结果。

要定位当前日期之前的最后一个条目,我们可以使用带有相关子查询的NOT EXISTS 条件。

SELECT 
    c.Date, 
    Nz(v.From, v1.From) AS [From], 
    Nz(v.To, v1.To) AS [To], 
    Nz(v.Amount, v1.Amount) AS [Amount]
FROM Calendar AS c
LEFT JOIN [Values] AS v 
    ON c.Date >= v.From AND c.Date <= v.To
LEFT JOIN [Values] AS v1 
    ON v1.To < c.Date
    AND NOT EXISTS (
        SELECT 1 FROM [Values] v2 WHERE v2.To < c.Date AND v2.To > v1.To
    )

PS :长期以来,SQL 中的一个好习惯是避免老式的、隐式的JOINs,并始终使用显式的JOINs。

【讨论】:

  • 我总是遇到语法错误,但看不到原因。
  • @Paintitblack3k:你到底遇到了哪个错误?
  • @Paintitblack3k :我修复了列名中的一个小问题,如果这适用于您现在,请告诉我...谢谢!
  • 我得到“''中的语法错误(缺少运算符)。” (希望我准确地翻译了它)。也许它依赖于 MS Access 版本?
【解决方案2】:

您可以使用 LEFT JOIN 和子查询来获取最后的金额:

SELECT c.Date, v.From, v.To, 
Nz(
  v.Amount, 
  (SELECT MAX([Values].Amount) FROM [Values] WHERE [Values].From = 
    (SELECT MAX([Values].From) FROM [Values] WHERE [Values].From <= c.Date))
) AS Amount
FROM Calendar AS c LEFT JOIN [Values] AS v
ON c.Date>=v.From AND c.Date<=v.To;

【讨论】:

  • 这很好用。明天我会用其他一些案例来强调它。对于我描述的情况,它的效果非常好。
  • SELECT c.Date, v.From, v.To, Nz( v.Amount, (SELECT Top 1 [Values].Amount FROM [Values] WHERE [Values].From &lt;=c.Date ORDER BY v.From DESC) ) AS Amount FROM Calendar AS c LEFT JOIN [Values] AS v ON (c.Date&gt;=v.From) AND (c.Date&lt;=v.To); 只有一个带有 TOP 1 和 ORDER BY [Values].FROM DESC 的子查询怎么样。这不起作用,但为什么?
  • TOP 1 用于返回 ACCESS 的结果集,使用 MAX() 而不使用 ORDER BY:SELECT c.Date, v.From, v.To, Nz( v.Amount, (SELECT MAX( [Values].Amount) FROM [Values] WHERE [Values].From &lt;=c.Date)) AS Amount FROM Calendar AS c LEFT JOIN [Values] AS v ON (c.Date&gt;=v.From) AND (c.Date&lt;=v.To);
猜你喜欢
  • 1970-01-01
  • 2021-06-03
  • 1970-01-01
  • 1970-01-01
  • 2022-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-17
相关资源
最近更新 更多