SQLITE查询,如果最后一行符合条件,则检查前面的行匹配不同的条件

时间:2013-07-27 09:43:09

标签: sqlite

我发现很难解决这个问题,我无法在任何地方找到任何答案:

假设我有一张这样的桌子,我只是以水果为例:

Fruit | Date | Value
=================================
Apple |    1 | other_random_value
Apple |    2 | some_value_1
Apple |    3 | some_value_2
Pear  |    1 | other_random_value
Pear  |    2 | unexpected_value_1
Pear  |    3 | some_value_2

一切都将由Fruit订购,然后是Date。

基本上,如果最后一行(对于每个水果)是some_value_2,但前面的那一行不是some_value_1,我想只匹配那些水果(即在这种情况下,梨)。

所以,some_value_2我总是希望在特定水果的某个特定值的行之后来,如果不是,我想标记那些特定水果的错误。匹配some_value_2之前没有任何内容的情况也是很好的,但是如果这太复杂了我可以单独匹配它并且只检查some_value_2不是第一行,我认为这不是一个困难的查询。 / p>

编辑:此外,能够匹配前面的值是意外的任何连续行会很好,虽然我主要关心最后2行。因此,如果能够匹配所有连续行导致更简单和更好的查询,那么我可能会这样做。我将同时进行INSERT(进入警报表),所以如果我将它标记为ERROR,如果它是最后两行,则警告如果不是,那将是非常好的。虽然我不知道从哪里开始写一个查询来做到这一点。还有一个表现良好的查询是必须的,因为我将在大型数据集中使用它。

修改

这是我最后使用的,它很慢,但如果我将Date编入索引,那就不是那么糟糕了:

SELECT c.Id AS CId, c.Fruit AS CFruit,
       c.Date AS CDate, c.Value AS CValue,
       (SELECT Id
        FROM fruits
        WHERE Fruit = c.Fruit
        AND Date >= c.Date
        AND Id > c.Id
        ORDER BY Date, Id) AS NId, n.Fruit AS NFruit,
       n.Date AS NDate, n.Value AS NValue
FROM fruits AS c
JOIN fruits AS n ON n.Id = NId
ORDER BY c.Date, c.Id

我可能会在某个时候再次尝试Joachim的方法,因为我意识到我得到了很多我不太关心的结果。或者我甚至可能尝试以某种方式将两者结合起来并酌情委托给INFO / ERROR ......


已解决:我使用了与用于获取NId相同的SELECT语句,并使用了SELECT COUNT(*)而不是SELECT Id。这告诉我当前结果之后的结果数量。然后我只使用CASE运算符将其转换为名为Latest :)的布尔字段。所以我有效地结合了Nicolas和Joachim的方法。性能似乎还不错,可能是因为SQLite缓存了结果。

1 个答案:

答案 0 :(得分:0)

SQLite(据我所知)对此有效的运算符有点低,所以这是我现在能想到的最好的:)

SELECT Fruit FROM fruits
WHERE ( SELECT COUNT(*) FROM fruits f 
        WHERE f.fruit=fruits.fruit 
          AND f.date > fruits.date ) = 1
  AND fruits.value <> 'some_value_1'
INTERSECT 
SELECT Fruit FROM fruits
WHERE ( SELECT COUNT(*) FROM fruits f 
        WHERE f.fruit=fruits.fruit 
          AND f.date > fruits.date ) = 0
  AND fruits.value = 'some_value_2'

An SQLfiddle to test with