SQL-如何查找两行之间缺少值的条目

时间:2018-07-28 02:36:20

标签: sql presto

我们正在使用Presto SQL。我已经花了数小时试图寻找这个问题的答案,但是找不到答案,而且很难找到。解决此问题为解决许多问题打开了大门。

我需要编写一个查询,尝试查找存在REQUEST_CANCEL&CHARGED但缺少CANCEL_ACCOUNT的所有条目。

CHARGED和CANCEL_ACCOUNT应该始终排在REQUEST_CANCEL之后。

表名:CUSTOMER_INFO

|DATE_TIME|CUST_ID |ACTION        |
|20180726 |1234    |CHARGED       |
|20180726 |1234    |CANCEL_ACCOUNT|
|20180726 |1234    |REQUEST_CANCEL|

所有这些值都存在于同一表中。这就是我到目前为止所拥有的。

SELECT *
FROM
    (SELECT *
    FROM CUSTOMER_INFO
        WHERE 
        DATE_TIME = 20180726
        AND ACTION = REQUEST_CANCEL) as a
JOIN
    (SELECT *
    FROM CUSTOMER_INFO
    WHERE
    DATE_TIME = 20180726
    AND ACTION = CHARGED) as b
ON a.CUST_ID = b.CUST_ID
WHERE 
    a.TIME < b.TIME

让我以一种有意义的方式进行解释。

A = REQUEST_CANCEL
B = CANCEL_ACCOUNT
C = CHARGED

如何查询何时存在A和C但缺少B。序列必须精确地是A> B>C。这实际上是在查询两个存在的值之间不存在的东西。在我当前的查询中,可以在两个值之间返回B,而这并不是我想要的。

2 个答案:

答案 0 :(得分:0)

我认为您正在搜索NOT EXISTS和一个关联的子查询。

SELECT *
       FROM (SELECT *
                    FROM customer_info
                    WHERE action = 'REQUEST_CANCEL') rc
            INNER JOIN (SELECT *
                               FROM customer_info
                               WHERE action = 'CHARGED') c
                       ON c.cust_id = rc.cust_id
                          AND c.date_time >= rc.date_time
       WHERE NOT EXISTS (SELECT *
                                FROM customer_info ca
                                WHERE ca.cust_id = rc.cust_id
                                      AND ca.action = 'CANCEL_ACCOUNT'
                                      AND ca.date_time >= rc.date_time
                                      AND ca.date_time <= c.date_time);

答案 1 :(得分:0)

使用group byhaving

select cust_id
from customer_info ci
where date_time = 20180726 and
      action in ('REQUEST_CANCEL', 'CHARGED', 'CANCEL_ACCOUNT')
group by cust_id
having sum(case when action = 'REQUEST_CANCEL' then 1 else 0 end) > 0 and
       sum(case when action = 'CHARGED' then 1 else 0 end) > 0 and
       sum(case when action = 'CANCEL_ACCOUNT' then 1 else 0 end) = 0 ;

每个sum()都会为执行该操作的客户计算匹配记录的数量。 > 0说一个存在。 = 0说不存在。

数据库对于此逻辑无关紧要。 Here是使用MySQL的SQL Fiddle。