0

異なる時間に異なるビンをポーリングし、重みに基づいて各ビン内のウィジェットの数を計算するアプリケーションがあります。ポーリングは数分ごとに実行され、結果にタイムスタンプが付けられ、MySQL テーブルに追加されます。この表には、以下の 3 つの列が含まれています。この例では 3 つのビン (A、B、および C) を示していますが、同じウィジェットに対して 1 から 10 のビンが存在する可能性があります。(小さなウィジェットは 1 つまたは 2 つのビンに収まる可能性があり、大きなウィジェットはより多くのビンを占有する可能性があります)

timestamp   bin Widget_Count
--------------------------
1           A       8
2           B       7
3           C       4
4           A       1
5           B       3
6           C       5
7           A       6
8           B       7
9           C       2

アプリケーションは「株式履歴」レポートを生成する必要があります。これには、各タイムステップで合計数を計算することが含まれます。そのタイムステップでのすべてのビンからのアイテムの。この例では、レポートにはタイムスタンプ列とその下の CountHistory 列 (最後の列) のみが含まれます (他の列は計算を示すためだけに示されています)。

時間 1 で、A はポーリングされ、8 つのウィジェットを持っています。B と C はポーリングされていません。したがって、合計は 8 です。

時間 2 で、B はポーリングされ、7 つのウィジェットを持っています。だから合計は17

時間 3 で、C はポーリングされ、4 つのウィジェットを持っています。だから合計は19

時間 4 で、A は再度ポーリングし、ウィジェットは 1 つだけです。合計は 1+4+7=12 です

..等々。

timestamp   bin Widget_     A   B   C   CountHistory
                Count                    (stock flow)
--------------------------------------------------------
1           A       8       8   0   0       8
2           B       7       8   7   0       15
3           C       4       8   7   4       19
4           A       1       1   7   4       12
5           B       3       1   3   4       8
6           C       5       1   3   5       9
7           A       6       6   3   5       14
8           B       7       6   7   5       18
9           C       2       6   7   2       15

これについて最善の方法を教えていただければ幸いです。一時テーブルを作成し、カーソルを使用して各レコードをスクロールしようとしましたが、正しいクエリを取得できませんでした。

(以前に関連する質問をしたことがありましたが、質問を正しく組み立てておらず、例も間抜けでした。Microsoft Access のクエリ (ビュー) に関するヘルプが必要です)

4

2 に答える 2

2

私はこれがあなたが必要とすることをするだろうと思います。内部クエリは、タイムスタンプごとに各ビンが変更された最新のタイムスタンプを検索します。

SELECT m.timestamp, SUM(w.Widget_Count) AS CountHistory
FROM (
    SELECT a.timestamp, b.bin, MAX(b.timestamp) AS intMostRecentTimestamp
    FROM WidgetTable a
        CROSS JOIN WidgetTable b
    WHERE a.timestamp >= b.timestamp
    GROUP BY a.timestamp, b.bin, a.Widget_Count
) m 
    INNER JOIN WidgetTable w ON m.intMostRecentTimestamp = w.timestamp
GROUP BY m.timestamp
ORDER BY m.timestamp
于 2009-12-09T22:18:52.863 に答える
1

実際のモデル (DDL) とデータ (予想される出力を含む) がなければ、実際の構文チェック済みのサンプル SQL を提供しようとするかどうかわかりません。これは、アプリケーション コードやカーソルを使用して簡単に実行できると思いますが、単一のクエリで実行できると思います。

つまり、次のようなものになります。この 100% 疑似コードを考えてみてください。

SELECT
 timestamp,
 bin,
 widget_count,
 (SELECT A that is most recent and <= current row's timestamp) A,
 (SELECT B that is most recent and <= current row's timestamp) B,
 (SELECT C that is most recent and <= current row's timestamp) C,
 (SELECT sum of last three columns) CountHistory
FROM
 widget_bin_table

おそらく、サブクエリの代わりに結合を使用して行うことができ、結合はおそらくより効率的です。しかし、あなたはその考えを理解します。


編集:わかりました、質問は脳の血を流し、満足するまで解決するまで休むことができませんでした. それから私は更新を投稿するために戻ってきました.Paulはすでによりエレガントな解決策で答えていました. :)

誰かが気にする場合に備えて、SQLを(SQL Serverを使用して)動作させる私のソリューションを次に示します。

SELECT
    timestamp, bin, widget_count, A, B, C, A + B + C CountHistory
FROM
    (
     SELECT
        wb.timestamp,
        wb.bin,
        wb.widget_count,
        ISNULL((SELECT TOP 1 widget_count FROM widget_bin wb1 WHERE wb1.bin = 'A' 
                AND wb1.timestamp <= wb.timestamp ORDER BY wb1.timestamp DESC), 0) A,
        ISNULL((SELECT TOP 1 widget_count FROM widget_bin wb1 WHERE wb1.bin = 'B' 
                AND wb1.timestamp <= wb.timestamp ORDER BY wb1.timestamp DESC), 0) B,
        ISNULL((SELECT TOP 1 widget_count FROM widget_bin wb1 WHERE wb1.bin = 'C' 
                AND wb1.timestamp <= wb.timestamp ORDER BY wb1.timestamp DESC), 0) C
     FROM
        widget_bin wb
    ) sub
于 2009-12-09T21:52:57.817 に答える