以下查询返回给定月份中具有USERS
的所有SUM(AMOUNT) > 10
。即使一个月内的用户不符合标准,它也会包含一个月内的用户。
但是我想将此查询转换为必须满足条件USERS
的所有SUM(AMOUNT) > 10
,每个月(即从表中的第一个月到最后一个月) )。
采用另一种方式,排除每个月不符合SUM(AMOUNT) > 10
的用户。
select USERS, to_char(transaction_date, 'YYYY-MM') as month
from Table
GROUP BY USERS, month
HAVING SUM(AMOUNT) > 10;
答案 0 :(得分:0)
一种方法是使用生成的日历表代表数据集中的所有月份。我们可以将此日历表保留到您当前的查询中,然后按用户汇总所有月份:
WITH months AS (
SELECT DISTINCT TO_CHAR(transaction_date, 'YYYY-MM') AS month
FROM yourTable
),
cte AS (
SELECT USERS, TO_CHAR(transaction_date, 'YYYY-MM') AS month
FROM yourTable
GROUP BY USERS, month
HAVING SUM(AMOUNT) > 10
)
SELECT
t.USERS
FROM months m
LEFT JOIN cte t
ON m.month = t.month
GROUP BY
t.USERS
HAVING
COUNT(t.USERS) = (SELECT COUNT(*) FROM months);
上面的HAVING
子句断言,用户匹配的月数实际上是月总数。这意味着用户符合每月的总计标准。
答案 1 :(得分:0)
一个选择是使用sign(amount-10)
与sign(amount)
逻辑作为
SELECT q.users
FROM
(
with tab(users, transaction_date,amount) as
(
select 1,date'2018-11-24',8 union all
select 1,date'2018-11-24',18 union all
select 2,date'2018-10-24',13 union all
select 3,date'2018-11-24',18 union all
select 3,date'2018-10-24',28 union all
select 3,date'2018-09-24', 3 union all
select 4,date'2018-10-24',28
)
SELECT users, to_char(transaction_date, 'YYYY-MM') as month,
sum(sign(amount-10)) as cnt1,
sum(sign(amount)) as cnt2
FROM tab t
GROUP BY users, month
) q
GROUP BY q.users
HAVING sum(q.cnt1) = sum(q.cnt2)
GROUP BY q.users
users
-----
2
4
答案 2 :(得分:0)
也许您可以使用相关的子查询,例如:
jTable
答案 3 :(得分:0)
您需要将> 10的月份数与最短日期和最长日期之间的月份数进行比较:
SELECT users, Count(flag) AS months, Min(mth), Max(mth)
FROM
(
SELECT users, date_trunc('month',transaction_date) AS mth,
CASE WHEN Sum(amount) > 10 THEN 1 end AS flag
FROM tab t
GROUP BY users, mth
) AS dt
GROUP BY users
HAVING -- adding the number of months > 10 to the min date and compare to max
Min(mth) + (INTERVAL '1' MONTH * (Count(flag)-1)) = Max(mth)
如果缺少的月份不算在内,那将是简单的count(flag) = count(*)