我有一个简单的表,其中包含一个'reader'对象的状态历史记录。该状态可以是ACTIVE或INACTIVE。现在我想要查询一下,它会挑选所有读者,这些读者在给定的时期内处于ACTIVE状态。下图显示了我的意思:在显示的时间段内,带有绿色“生命线”的'读者'处于活动状态;所以它们将在查询中返回。在给定的时间段内选择状态历史表的活动状态
的TABEL ReaderActivity
看起来像这样(仅作为示例,而不是上面的匹配图像):
reader_id | state | timestamp
1 | ACTIVE | 1467331201089
2 | ACTIVE | 1467332454545
1 | INACTIVE | 1467348875254
3 | ACTIVE | 1467350416546
1 | ACTIVE | 1467351871123
2 | INACTIVE | 1467352111545
当然,有一个Reader
实体向这个reader_id
被映射到哪个。
我需要对此有一个JPA查询,但是我有问题,包括读者进入结果,它没有'上升沿'(状态从INACTIVE变为ACTIVE)我们期待的期间)。
我看基本上也查询的部分:
- 首先,选择所有具有上升边缘。这很简单:
SELECT DISTINCT a.reader FROM ReaderActivity a WHERE a.timestamp >= :startTimestamp AND a.timestamp < :endTimestamp AND a.state = 'ACTIVE'
- 其次,它应该追加到所有读者上面的列表中,它在期间开始之前具有最后状态ACTIVE。这是我没有正确地得到:我想(合并成拳头查询):
SELECT DISTINCT a.reader FROM ReaderActivity a WHERE a.timestamp >= :startTimestamp AND a.timestamp < :endTimestamp AND a.state = 'ACTIVE' or (SELECT aa.reader FROM ReaderActivity aa where aa.reader = a.reader AND aa.timestamp < :startTimestamp AND aa.state = 'ACTIVE' GROUP BY aa.reader ORDER BY max(aa.timestamp)) != null
这将返回也是红色标记的图像中的阅读器上面,因为在子查询中AND aa.state = 'ACTIVE'
,我们已经筛选出所有ACTIVE状态,所以最后一个当然是ACTIVE。我应该选择开始时间段之前的最后一个状态,然后检查是否为ACTIVE。但是如何?
任何人都可以让我以正确的方式吗? 在此先感谢!
非常感谢卢克!我错过了使用'... where in()...'[[]]的可能性 - 我的完整查询现在是:'SELECT DISTINCT a.reader FROM ReaderActivity a WHERE a.timestamp> =:startTs AND a.timestamp <:endTs AND a.state ='ACTIVE'OR(a.timestamp IN(SELECT MAX(b.timestamp)FROM ReaderActivity b WHERE b.timestamp <:startTs GROUP BY b.reader)AND a.state ='ACTIVE') ' - 一个问题:为什么你在最后的方括号中加上'state',('...和a。[state] = ...')? – badera
我们不能解决您的重要提示*唯一需要注意的是,如果由于某种原因,reader_id'a'在毫秒级被设置为“INACTIVE”... *通过添加...在子选择的where子句中where where b.reader_id = a.reader_id'? – badera
为了回应你的第一个问题,从状态中删除括号不会改变查询,也不会在那里。当列由空格分隔的单词组成时,需要在列周围使用括号将一列分组在一起。出于某种原因,我读状态为两个单词(不知道如何)。回答你的第二个问题,是的!在a.reader_id = b.reader_id上添加where过滤器将防止带回'INACTIVE'记录。我会改变查询来反映这一点。 @badera – Luke