2017-01-12 84 views
2

我們需要找到類似的數據幫助..
- 在多少天「大小」,「類型」 ABC的價值將觸及「」圖(50本例)。
MySQL查詢得到的平均數據消費

  • 類型 「ABC」 的尺寸每天都在增加。
  • 有可能是在單個日期的多個條目
  • 有可能是在列 「類型」 的多個值

表消耗

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 

輸出:ABC將觸及50在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每日平均增長。 現在我們可以用這個查詢來計算需要的天數((total- [max size])/ [daily avg growth])((50 - 25)/ 3.3333)= 7.5天。注意在查詢中使用CEIL,因此結果爲8天 它將上面的查詢用作交付表。

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,這是非常棒的。它是如此的解釋性和一步一步的執行。我嘗試過的一個問題是,我一直試圖做到這一點,並做了一塌糊塗,但你建立的邏輯非常好。非常感謝你的幫助 :) –