带有 LEFT JOIN 和 MAX 的 LibreOffice HSQLDB WHERE 子句?

Posted

技术标签:

【中文标题】带有 LEFT JOIN 和 MAX 的 LibreOffice HSQLDB WHERE 子句?【英文标题】:LibreOffice HSQLDB WHERE clause with LEFT JOIN and MAX? 【发布时间】:2021-12-30 00:08:08 【问题描述】:

我运行的是macOS 11.6,LibreOffice 7.2.2.2,HSQLDB(我的理解是这是v.1.8,但不知道如何验证)

我是 SQL 的新手,我正在尝试编写数据库来维护俱乐部会员名册。我正在尝试在数据库中找到应该向其发送续订信的每个人。怪癖是,如果一个人过去从未付款,他们应该收到续订信。最近没有续约的老会员是不会续约的,显然每个人只能收到一封信。我创建了一个玩具示例来显示我遇到的问题...

Members table:
Key (Integer, Primary key, Autoincrement)
Name (Varchar)
+-----+----------+
| Key | Name     |
+-----+----------+
|  0  | Abby     |
|  1  | Bob      |
|  2  | Dave     |
|  3  | Ellen    |
+-----+----------+

Payments table:
Key (Integer, Primary Key, autoincrement)
MemberKey (Integer, foreign key to Member table)
Payment Date (Date)
+-----+-----------+--------------+
| Key | MemberKey | Payment Date |
+-----+-----------+--------------+
|  0  |     0     | 2020-05-23   |
|  1  |     0     | 2021-06-12   |
|  2  |     1     | 2016-05-28   |
|  3  |     2     | 2020-07-02   |
+-----+-----------+--------------+

我发现包含所有人的唯一方法是使用 LEFT JOIN。我发现选择最近付款的唯一方法是使用 MAX。以下查询生成每个人最近付款的列表,包括从未付款的人:

SELECT "Members"."Key", "Members"."Name", MAX( "Payments"."Payment Date" ) AS "Last Payment"
FROM  oj "Members" LEFT OUTER JOIN "Payments" ON "Members"."Key" = "Payments"."MemberKey" 
GROUP BY "Members"."Key", "Members"."Name"

它返回下面的结果,其中只包括一次所有成员(Abby 有 2 次付款,但最近一次付款只出现一次)。不幸的是,它仍然包括像 Bob 这样的人,他们已经离开俱乐部很长时间了,我们不想向他们发送续约通知。

+-----+----------+--------------+
| Key | Name     | Last Payment |
+-----+----------+--------------+
|  0  | Abby     | 2021-06-12   |
|  1  | Bob      | 2016-05-28   |
|  2  | Dave     | 2020-07-02   |
|  3  | Ellen    |              |
+-----+----------+--------------+

当我尝试对 Last Payment 执行 any 类型的条件操作以确定它是否足够新以包含在更新通知。例如,在 HSQLDB 中,下面的查询返回错误“无法加载数据内容。不是条件”。与第一个查询相比,此查询的唯一变化是添加了 WHERE 子句。

SELECT "Members"."Key", "Members"."Name", MAX( "Payments"."Payment Date" ) AS "Last Payment"
FROM  oj "Members" LEFT OUTER JOIN "Payments" ON "Members"."Key" = "Payments"."MemberKey" 
WHERE "Last Payment" >= '2020-01-01'
GROUP BY "Members"."Key", "Members"."Name"

所需的输出应如下所示:

+-----+----------+--------------+
| Key | Name     | Last Payment |
+-----+----------+--------------+
|  0  | Abby     | 2021-06-12   |
|  2  | Dave     | 2020-07-02   |
|  3  | Ellen    |              |
+-----+----------+--------------+

我一直在网上搜索任何看起来相关的东西。我已经尝试过“HAVING”子句——我可以让它们与 COUNT(*) 函数一起使用,但我不能让它们与 MAX(*) 函数一起使用。我尝试使用我的第一个查询作为子查询,并在主查询中对“最后一次付款”应用 WHERE 子句。我已经尝试过人们说在 mysql 中工作的解决方案,但我无法让他们在 HSQLDB 中工作。我尝试使用第一个查询作为视图,并针对视图编写查询。我已经尝试了十几种我什至不记得的东西。上面第一个查询之后的所有内容都会引发错误。我想包含我的玩具数据库,但找不到将其附加到帖子的方法。

有人可以帮忙吗?

【问题讨论】:

Ratslinger 或ask.libreoffice.org/c/english/5 的其他人定期回答任何基本问题。您可以在该站点上附加示例 .odb。 这个问题的格式和例子都很好。 【参考方案1】:

这对我有用。

SELECT "Members"."Key", "Members"."Name", MAX( "Payments"."Payment Date" ) AS "Last Payment"
FROM oj "Members" LEFT OUTER JOIN "Payments" ON "Members"."Key" = "Payments"."MemberKey"
    WHERE "Payments"."Payment Date" >= '2020-01-01'
    OR "Payments"."Payment Date" IS NULL
GROUP BY "Members"."Key", "Members"."Name"

结果:

这也有效。

SELECT "Members"."Key", "Members"."Name", MAX( "Payments"."Payment Date" ) AS "Last Payment"
FROM  oj "Members" LEFT OUTER JOIN "Payments" ON "Members"."Key" = "Payments"."MemberKey" 
WHERE "Payments"."Payment Date" >= '2020-01-01'
    OR "Payments"."Payment Date" IS NULL
GROUP BY "Members"."Key", "Members"."Name"

也许您遇到的问题是“最后一次付款”只是一个列标题,而不是任何列的实际名称。

【讨论】:

第一个查询只给我“语法错误”,我不知道为什么。我没有看到任何语法错误,除了在它不喜欢的左外连接中使用 WHERE 子句,即使它看起来没问题。第二个查询有效,谢谢,并指出我有一个误解。如果我不指定别名,则上次付款的列标题显示为 MAX("Payments"."Payment Date")。无论我如何尝试引用 MAX 列(“Payments”.“Payment Date”),它都不起作用。也不用别名。我没有意识到我可以使用原始列名。非常感谢!

以上是关于带有 LEFT JOIN 和 MAX 的 LibreOffice HSQLDB WHERE 子句?的主要内容,如果未能解决你的问题,请参考以下文章

SQL join left get MAX(date)

带有 UNNEST、LEFT JOIN 和 WHERE 语句的 Bigquery

带有“Group by”、“max”和“join”的 SQL 请求?

带有 LEFT JOIN 和 IF 语句的有限 GROUP_CONCAT

带有子查询语法的 LEFT OUTER JOIN

带有 LEFT JOIN 和 GROUP BY 的 COUNT(*) 在 MySQL 中包含 NULL