0

この問題に頭を悩ませるのは難しいと感じています。この特定の問題に対する答えはどこにも見つかりませんでした。

このようなテーブルがあるとします。例としてフルーツを使用しています。

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

すべて果物、次に日付の順に並べられます。

基本的に、(各果物の) 最後の行が some_value_2 であるが、その前の行が some_value_1 でない場合、それらの果物 (つまり、この場合は Pear) だけに一致させたいと考えています。

そのため、some_value_2 は、その特定の果物の特定の値を持つ行の後に来ることを常に期待しており、そうでない場合は、それらの特定の果物に対してエラーをフラグ付けしたいと考えています。some_value_2 の前に何もない場合も一致させるとよいでしょうが、これが複雑すぎる場合は、個別に一致させて、some_value_2 が最初の行ではないことを確認するだけで済みますが、これは難しいクエリではないと思います。

編集:また、前の値が予期しない連続する行に一致できると便利ですが、私は主に最後の 2 行を気にします。したがって、連続するすべての行を一致させることができれば、よりシンプルでパフォーマンスの高いクエリが得られるのであれば、それを採用する可能性があります。同時に (アラート テーブルへの) INSERT を実行する予定なので、最後の 2 行である場合は ERROR としてフラグを立て、そうでない場合は WARNING としてフラグを立てることができれば、それは本当に素晴らしいことです。それを行うクエリの作成をどこから始めればよいかわかりませんが。また、大規模なデータセット全体でこれを使用するため、適切に実行されるクエリを用意する必要があります。

編集:

これは私が最後に使用したものです。かなり遅いですが、日付にインデックスを付ければ、それほど悪くはありません。

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 の方法をもう一度試すかもしれません。または、何らかの形で 2 つを組み込み、必要に応じて INFO/ERROR に委任することもできます...


解決済み: NId を取得するために使用したのと同じ SELECT ステートメントを使用し、SELECT Id の代わりに SELECT COUNT(*) を使用しました。これは、現在の結果の後の結果の数を教えてくれました。次に、CASE 演算子を使用して、Latest :) というブール値フィールドに変換しました。そこで、ニコラスとヨアヒムの方法を効果的に組み合わせました。おそらく SQLite が結果をキャッシュするため、パフォーマンスはまだ問題ないようです。

4

2 に答える 2

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'

でテストする SQLfiddle

于 2013-07-27T11:13:11.197 に答える