0

我们有一个如下所示的数据集:

ID       eventType     date
--------------------------------
1        foo           2 March 2013
2        foo           3 March 2013
3        bar           3 March 2013
4        foo           5 March 2013
5        foo           6 March 2013
6        bar           7 March 2013
7        baz           8 March 2013

我可以很容易地从这个列表中得到唯一的eventTypes列表。但是,我如何查询eventTypes首先出现在 BETWEENstartDateendDate. 我希望能够有一个从 2013 年 3 月 7 日到 2013 年 3 月 10 日的日期范围,并得到一个返回 1 的计数,因为baz值是eventType在该日期范围内新出现的。另一方面,2013 年 3 月 5 日至 2013 年 3 月 7 日的日期范围将返回计数 0,因为eventTypes在该范围内没有新出现。

4

4 回答 4

1

我只想看看使用MIN聚合函数在查询结束日期之前查找事件类型的最早出现。然后我会看看是否有任何事件在范围的开始日期之后有最早的事件。

SELECT event_type, date_value
from (
  SELECT event_type, min(date_value) as date_value
  from your_table
  where date_value <= date '2013-03-10'
  group by event_type
)
where date_value >= date '2013-03-07'
于 2013-02-06T21:08:33.560 回答
1

我认为这应该对你有用。基本上加入表反对自己:

SELECT COUNT(DISTINCT T.EventType)
FROM YourTable T
   LEFT JOIN YourTable T2 ON T.eventType = T2.eventType AND T2.dateField < to_date('2013-03-07','yyyy-mm-dd')
WHERE T.DateField BETWEEN to_date('2013-03-07','yyyy-mm-dd') 
  AND to_date('2013-03-10','yyyy-mm-dd')
       AND T2.Id IS NULL

这是SQL Fiddle

- 编辑

正如@JoachimIsaksson 正确指出的那样,您可以轻松(并且可能最好)将其更改LEFT JOIN为:

   LEFT JOIN YourTable T2 ON T.eventType = T2.eventType AND T2.dateField < T.dateField

祝你好运。

于 2013-02-06T18:55:13.460 回答
1

这样的事情应该可以解决问题:

SELECT COUNT(DISTINCT eventType)
FROM YOUR_TABLE T1
WHERE
    date BETWEEN :startDate AND :endDate
    AND NOT EXISTS (
        SELECT *
        FROM YOUR_TABLE T2
        WHERE T1.eventType = T2.eventType AND T2.date < :startDate
    )

用简单的英语:

  • 排除eventType在给定日期之前已经存在的所有行。
  • 然后只计算给定日期范围内剩余内容的不同出现次数。

另一种表达方式是使用 MINUS:

SELECT COUNT(*)
FROM (
  SELECT eventType
  FROM your_table
  WHERE date BETWEEN :startDate AND :endDate
  MINUS
  SELECT eventType
  FROM your_table
  WHERE date < :startDate
);

注意:在这种情况下不需要 COUNT(DISTINCT),因为 MINUS 意味着 DISTINCT,即 MINUS 的左侧将只返回唯一条目。

于 2013-02-06T19:20:54.003 回答
0

我不完全理解您的数据和问题,但我认为您可以使用分析函数按日期之间/range_between 和事件类型对数据进行分区。然后你的分区中有 rownum() 或 rank()/dense_rank() ,这将是你的序列。最低的序列。也许你的答案。

于 2013-02-06T19:17:14.307 回答