1

問題は、これらの顧客が特定の日付でどれくらいの期間、ジャークしていたかです。

私はSybaseに反対しています

テーブル history_data のこの簡略化されたテーブル構造の場合

表: history_of_jerkiness
処理日名 is_jerk
--------------- ----- -------
20090101 マット・トゥルー
20090101 ボブ偽        
20090101 アレックス・トゥルー        
20090101 キャロル・トゥルー        
20090102 マット・トゥルー        
20090102 ボブ トゥルー        
20090102 アレックス 偽        
20090102 キャロル・トゥルー        
20090103 マット・トゥルー        
20090103 ボブ トゥルー        
20090103 アレックス・トゥルー        
20090103 キャロル偽        

3 番目のレポートは、Matt が常に不機嫌で、Alex が急に不機嫌になり、Bob が 2 日間不機嫌であったことを示しているはずです。

ネームデイズジャーキー
----- ----------
マット 3
ボブ 2
アレックス 1

これらの期間を動的に見つけたいので、2 番目のレポートを実行すると、異なる結果が得られるはずです。

名前days_jerky
----- ----------
マット 2
ボブ 1
キャロル 2

ここで重要なのは、特定の日付より古い連続したスパンのみを見つけようとすることです。私はいくつかの手がかりを見つけましたが、非常にスマートでトリッキーな解決策が存在する問題のようです.

4

4 に答える 4

1

次の基準を満たすようにデータを構造化すると、これを簡単にすることができます...

すべての人は、彼らがジャークではない最初の記録を持っている必要があります

次のようなことができます...

SELECT
   name,
   MAX(date)   last_day_jerk_free
FROM
   jerkiness AS [data]
WHERE
   jerk = 'false'
   AND date <= 'a date'
GROUP BY
   name

基準日 (「日付」) が何であるかは既にわかっています。sybase についてはわかりませんが、「a data」と「last_day_jerk_free」の間の日数を取得するために使用できるコマンドがあると確信しています。

編集:

「ジャーキーではない」初期化レコードを人為的に作成する方法は複数あります。Will Rickers によって提案されたものは、共用体を含むサブクエリを使用します。ただし、これには 2 つ
の欠点があります... 1. サブクエリは、他の方法で使用された可能性のあるすべてのインデックスをマスクします

あるいは、Will Rickard の提案を取り入れて、集計を外側のクエリから内側のクエリに移動し (インデックスの使用を最大化します)、一般化された 2 番目のサブクエリと結合して、最初の jerky = false レコードを作成します...

SELECT name, DATEDIFF(day, MAX(processing_date), @run_date) AS days_jerky
FROM (

    SELECT name, MAX(processing_date) as processing_date
    FROM history_of_jerkiness
    WHERE is_jerk = 0 AND processing_date <= @run_date
    GROUP BY name

    UNION

    SELECT name, DATEADD(DAY, -1, MIN(processing_date))
    FROM history_of_jerkiness
    WHERE processing_date <= @run_date
    GROUP BY name

    ) as data
GROUP BY
   name

外側のクエリは、インデックスなしで max を実行する必要がありますが、レコード数を減らします (名前あたり n ではなく、名前あたり 2)。すべての名前が使用中のすべての日付の値を持つ必要がないため、レコードの数も削減されます。これを行うには他にも多くの方法があり、編集履歴で確認できるものもあります。

于 2009-03-11T16:32:45.720 に答える
1

「次の基準を満たすようにデータを構造化すると、これを簡単にすることができます...

すべての人は、嫌な奴ではない最初の記録を持っていなければならない」

データが満たすべき基準と満たすべきでない基準は、開発者ではなく、ユーザー次第です。

于 2009-06-18T16:50:51.577 に答える
0

これはどう:

select a.name,count(*) from history_of_jerkiness a
left join history_of_jerkiness b
on a.name = b.name 
and a.processing_date >= b.processing_date
and a.is_jerk = 'true'
where not exists
( select * from history_of_jerkiness c
  where a.name = c.name
  and c.processing_date between a.processing_date and b.processing_date
  and c.is_jerk = 'false'
)
and a.processing_date <= :a_certain_date;
于 2009-03-11T17:48:53.293 に答える