简体   繁体   English

如何获取分组并满足组内限制的条目?

[英]How to get entries which are grouped and satisfy restriction within the group?

In the table REPORT there are following 3 columns:在表 REPORT 中有以下 3 列:

  • RID - report id, which is not unique RID - 报告 id,它不是唯一的
  • TYPE - can be either new or cancel, report is identified by RID, so one report can have multiple cancellations and multiple new entries TYPE - 可以是新的或取消的,报告由 RID 标识,因此一个报告可以有多个取消和多个新条目
  • TIMESTAMP - is just a timestamp of when entry arrived TIMESTAMP - 只是条目到达时间的时间戳

Example below:下面的例子:

 RID |  Type   |    TIMESTAMP      |
-----+---------+-------------------+
4    |  New    | 2019-10-27 10:35  |
4    |  Cancel | 2019-10-27 09:35  |
3    |  Cancel | 2019-10-27 07:35  |
2    |  New    | 2019-10-27 07:35  |
1    |  Cancel | 2019-10-27 09:35  |
1    |  Cancel | 2019-10-27 08:35  |
1    |  New    | 2019-10-27 07:35  |

I'd like to get all reports which at some point were created and then canceled, so that the latest state is canceled.我想获取在某个时候创建然后取消的所有报告,以便取消最新的 state。 It is possible to have cancellations of non-existed reports, or entries with first cancellations and then new entries, all of those should be excluded.可能会取消不存在的报告,或者先取消然后新条目的条目,所有这些都应排除在外。

My attempt so far was to use nested query to get all cancellations, which have corresponding new entry, but do not know how to consider their timestamps into consideration, to exclude entries which have sequence cancel->new到目前为止,我的尝试是使用嵌套查询来获取所有取消,这些取消具有相应的新条目,但不知道如何考虑它们的时间戳,以排除具有序列 cancel->new 的条目

SELECT
    RID
FROM
    REPORT
WHERE
    TYPE = 'Cancel'
    AND RID IN (
        SELECT
            RID
        FROM
            REPORT
        WHERE
            TYPE = 'New'
    );

My expectation from the example is to get RID 1, I'm interested in only RIDs.我对示例的期望是获得 RID 1,我只对 RID 感兴趣。

Using: MySQL 5.7.27 InnoDB使用:MySQL 5.7.27 InnoDB

With EXISTS :随着EXISTS

select distinct r.rid
from report r
where r.type = 'Cancel' 
and exists (
  select 1 from report  
  where rid = r.rid and type='New' and timestamp < r.timestamp
) 

See the demo .请参阅演示
Or:或者:

select rid
from report
group by rid
having 
  min(case when type = 'New' then timestamp end) <
  min(case when type = 'Cancel' then timestamp end)

See the demo .请参阅演示
Results:结果:

| rid |
| --- |
| 1   |

I would get the latest type using a correlated subquery.我会使用相关子查询获得最新类型。 Then check for "cancel":然后检查“取消”:

select t.*
from t
where t.timestamp = (select max(t2.timestamp)
                     from t t2
                     where t2.rid = t.rid
                    ) and
      t.type = 'Cancel';

If you just want the rid and date, then another fun way uses aggregation:如果您只想rid和约会,那么另一种有趣的方式是使用聚合:

select rid, max(timestamp)
from t
group by rid
having max(timestamp) = max(case when type = 'Cancel' then timestamp end);

The logic here is to get timestamps where the maximum date is also the maximum cancel date.这里的逻辑是获取最大日期也是最大取消日期的时间戳。

Out of my head, probably with few typos, and probably not the best, but should be easy to understand...在我的脑海中,可能有几个错别字,可能不是最好的,但应该很容易理解......

SELECT n.RID FROM (
SELECT RID, TYPE, MIN(DATETIME) AS FirstAdd
FROM REPORT
WHERE TYPE = 'New'
GROUP BY RID, TYPE) n INNER JOIN (
SELECT RID, TYPE, MAX(DATETIME) AS LastCancel
FROM REPORT
WHERE TYPE = 'Cancel'
GROUP BY RID, TYPE) c ON n.RID = c.RID 
AND n.FirstAdd < c.LastCancel

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM