sql - 使用 MAX 的子句不能像我在 HIVE 查询中所期望的那样工作
问题描述
我正在尝试选择仅与表中的最大 DATE1 列和上个月匹配的记录。
我已经尝试使用标准的有子句语法来编写它,但这不起作用,所以我能够使用 CTE 获得我期望的结果。这个解决方案应该适用于我正在尝试做的事情,但我更想了解为什么 HAVING 子句不起作用。在这些示例中,MAX(DATE1)= 2018-02-28
我期望工作的查询
select
ID,
sum(money) as money,
date1
from
table1
group by
ID,
date1
having
date1 between add_months(max(date1),-1) and max(date1)
这将返回与此类似的结果集
| ID | Money | date1 |
|----|-------|------------|
| 1 | 50 | 2017-12-31 |
| 2 | 600 | 2018-01-31 |
| 3 | 200 | 2018-02-28 |
这个使用 CTE 的查询返回预期的结果集
with period as (
select
max(date1) as maxdate1,
add_months(max(date1),-1) as priordate1
from
table1
select
id,
sum(money),
date1
from
table1
join period on
1 = 1
where
date1 between priordate1 and maxdate1
group by
id,
date1
预期结果集
| ID | Money | date1 |
|----|-------|------------|
| 1 | 50 | 2018-02-28 |
| 2 | 600 | 2018-01-31 |
| 3 | 200 | 2018-02-28 |
解决方案
您的代码不起作用,因为date1
在group by
. 您可以使用窗口函数来避免join
:
select id, sum(money), maxdate1
from (select t1.*, max(date1) over () as maxdate1
from table1 t1
) t1
where date1 between add_months(maxdate1, -1) and maxdate1
group by id, maxdate1
推荐阅读
- bash - zsh throw 警告:此脚本已弃用,请参阅 git-completion.zsh
- javascript - 我的 Codewars 脚本未通过测试 ..?(系列中最大的 5 位数字)
- java - Netty 4.1:防止在服务器异常上发送 TCP ACK
- git - Git推送完全停止
- javascript - 如果我有 calendarID,部署脚本以更改其他用户的 Google 日历的最佳方式是什么?
- android - 辅助应用程序的 FirebaseMessaging.getInstance(firebaseApp) 应该是公共的,但它是私有的?
- r - map 函数如何知道在调用其缩写 (Ad) 时隔离调整后的列?
- angular - Angular 9 / Nativescript 6 代码共享应用程序不是为移动设备构建的 - 怀疑是 SASS 问题:
- c - 在 C 中,malloc 如何确定何时为新分配回收释放的空间?
- javascript - 在 vuex 和 node js 之间发送和获取参数