2017-01-12 9 views
2

は、我々のようなデータを見つけることに助けが必要
を平均データ消費量を取得する - どのように多くの日数では「サイズ」「タイプ」ABCの値は、この中で「」フィギュア(50触れます例)。タイプ "ABC" の
MySQLのクエリが...

  • サイズは毎日増加しています。 ABCは50に触れます:コラム "タイプ"

テーブルに複数の値がある可能性があり、単一の日付に複数のエントリ
  • があるかもしれません
  • DateTime |Type | size |total | seq_id 
    12-01-2016 | abc | 15 | 50 | 3 
    13-01-2016 | abc | 16 | 50 | 4 
    13-01-2016 | abc | 16 | 50 | 5 
    14-01-2016 | abc | 20 | 50 | 6 
    14-01-2016 | pqr | 10 | 50 | 7 
    15-01-2016 | abc | 25 | 50 | 8 
    

    出力を消費します1日の平均消費量に基づいてn日でn%増加した。

    +0

    あなたのテーブルに主キーはありません。時間が経つにつれて、これは問題になるかもしれません。 – Strawberry

    +0

    申し訳ありません私の悪い、私は例を作成中に主キーを追加することを忘れました - 今私の質問を編集しました –

    +0

    良い。また、この表に50が格納されているようなデザインが悪いようですね。 – Strawberry

    答えて

    3

    これを解決するための難しい質問は素晴らしいチャレンジでした。 しかし、私はあなたが必要とする答えを持っていると思います。

    作成テーブル/挿入データ

    CREATE TABLE consume 
        (`DateTime` VARCHAR(10), `Type` VARCHAR(3), `size` INT, `total` INT, `seq_id` INT) 
    ; 
    
    INSERT INTO consume 
        (`DateTime`, `Type`, `size`, `total`, `seq_id`) 
    VALUES 
        ('12-01-2016', 'abc', 15, 50, 3), 
        ('13-01-2016', 'abc', 16, 50, 4), 
        ('13-01-2016', 'abc', 16, 50, 5), 
        ('14-01-2016', 'abc', 20, 50, 6), 
        ('14-01-2016', 'pqr', 10, 50, 7), 
        ('15-01-2016', 'abc', 25, 50, 8) 
    ; 
    
    あなたが直面している問題は、あなたが日付の間の差を計算することができますので、必要なデータを取得することです

    .. 日付を注意してくださいはにする必要がありますこのクエリが正しく機能するためのシーケンスです。 14-01-2016、15-01-2016、16-01-2016、(...)

    SELECT DISTINCT 
         consume1.Type 
         , consume1.DateTime 
         , consume1.size 
         , consume2.DateTime 
         , consume2.size 
         , (consume2.size - consume1.size) size_diff 
        FROM 
         consume consume1 
        INNER JOIN 
         consume consume2 
        ON 
         consume1.DateTime < consume2.DateTime 
        WHERE 
         consume1.type = 'abc' 
         AND 
         consume2.type = 'abc' 
         AND 
         ((consume2.DateTime - consume1.DateTime) = 1) 
        ORDER BY 
         consume1.seq_id ASC 
    

    結果

    Type DateTime  size DateTime  size size_diff 
    ------ ---------- ------ ---------- ------ ----------- 
    abc  12-01-2016  15 13-01-2016  16   1 
    abc  13-01-2016  16 14-01-2016  20   4 
    abc  14-01-2016  20 15-01-2016  25   5 
    

    のように今、あなたは、あなたは正しいデータを持っていますこのクエリを使用して平均の平均サイズを計算できます。 上記のクエリを配信されたテーブルとして使用しています。必要なフィールドだけが選択されます。

    SELECT 
         TYPE 
        , AVG(size_diff) daily_avg_growth 
        FROM (
        SELECT DISTINCT 
          consume1.Type 
         , (consume2.size - consume1.size) size_diff 
        FROM 
         consume consume1 
        INNER JOIN 
         consume consume2 
        ON 
         consume1.DateTime < consume2.DateTime 
        WHERE 
         consume1.type = 'abc' 
         AND 
         consume2.type = 'abc' 
         AND 
         ((consume2.DateTime - consume1.DateTime) = 1) 
        ORDER BY 
         consume1.seq_id ASC 
        ) AS consume_per_day_filter 
    

    結果

    Type daily_avg_growth 
    ------ ------------------ 
    abc  3.3333    
    

    今、あなたは、タイプABCの毎日の平均成長を知っています。 このクエリで((合計 - [最大サイズ])/ [1日の平均成長率]((50 - 25)/ 3.3333)= 7.5日で必要な日数を計算できます。結果が8日であるため、icはクエリでCEILを使用しました。 配信されたテーブルとして上記のクエリを使用しています。

    SELECT 
        consume.Type 
    , CEIL((consume.total - MAX(consume.size))/daily_avg_growth) "days_needed_to_50" 
    FROM 
    consume 
    CROSS JOIN (
        SELECT 
        TYPE 
        , AVG(size_diff) daily_avg_growth 
        FROM (
        SELECT DISTINCT 
         consume1.Type 
        , (consume2.size - consume1.size) size_diff 
        FROM 
        consume consume1 
        INNER JOIN 
        consume consume2 
        ON 
        consume1.DateTime < consume2.DateTime 
        WHERE 
        consume1.type = 'abc' 
        AND 
        consume2.type = 'abc' 
        AND 
        ((consume2.DateTime - consume1.DateTime) = 1) 
        ORDER BY 
        consume1.seq_id ASC 
    ) 
        AS consume_per_day_filter 
    ) 
        AS consume_per_day_filter_sum 
    WHERE 
    consume.type = 'abc' 
    

    結果

    Type days_needed_to_50 
    ------ ------------------- 
    abc      8 
    
    +1

    DDLを提供するためにうまくいっていますが、GROUP BY句はこのようなクエリでは機能しません。 – Strawberry

    +0

    @Strawberry INNER JOINは重複を生成し、GROUP BYを使用してGROUP BYを使用して集計関数を使用せずに正しくフィルタリングしていますが、かなり醜い方法です...答えを更新してDISTINCTをフィルタリングしていますクエリをより明確にするために重複を削除してください。 –

    +1

    @RaymondNijland、これは素晴らしいです。それは非常に説明的で、ステップバイステップでとても良いステップです。私の試みの問題は、私が一度にこれをやろうとしていて、完全に混乱したのですが、あなたが構築するロジックは本当に良いです。あなたの助けをたくさんありがとう:) –