簡體   English   中英

執行按名稱分組結果的行和列之間的操作的 SQL 查詢

[英]SQL query to perform operations between rows and columns grouping the results by name

我有一個 Mysql 數據庫,其中包含一個用於存儲來自已執行任務的數據的表。 該表包含與任務狀態(初始化、就緒、執行)相對應的日期。 我需要執行允許我在這些日期獲得結果的操作,問題是這些操作是在不同的行和列之間進行的。

這是我的數據表的示例。 日期是 Unix TimeStamp (bigint) 中的值。 由於時間在Unix(整數),下表我只放了一個說明性數字(它們可以以相同的方式用於解決方案)

    +----------+-----+--------------+---------+---------+---------+
    | taskName |  Id |    State     |  Date1  |  Date2  |  Date3  |
    +----------+-----+--------------+---------+---------+---------+
    |   T10    |  1  | initializing |     1   |   2     |     3   |
    |   T10    |  1  |    ready     |     4   |   5     |     6   |  
    |   T10    |  1  |   executed   |     7   |   8     |     9   |
    |   T20    |  2  | initializing |     10  |   11    |     12  |
    |   T20    |  2  |    ready     |     13  |   14    |     15  | 
    |   T20    |  2  |   executed   |     16  |   17    |     18  |
    |   T10    |  3  | initializing |     72  |   74    |     76  |
    |   T10    |  3  |    ready     |     78  |   80    |     82  |  
    |   T10    |  3  |   executed   |     84  |   86    |     88  |
    |   T30    |  4  | initializing |     28  |   29    |     30  |
    |   T30    |  4  |    ready     |     31  |   32    |     33  | 
    |   T30    |  4  |   executed   |     34  |   35    |     36  |

                                     ... 
    +----------+-----+--------------+---------+---------+---------+

  • 在 Date1 列中(dt1 = 達到狀態的時間)
  • 在 Date2 列中(dt2 = 狀態加載時間)
  • 在 Date3 列中(dt3 = 狀態完成的時間)

我需要在具有相同 ID 的任務日期之間以及按任務名稱對結果進行分組后執行操作。 操作是(考慮具有相同 id 的任務):

  • dt2(狀態 = 就緒)- dt1(狀態 = 初始化)> oepration1
  • dt3(狀態 = 已執行)- dt2(狀態 = 就緒)> 操作 2
  • dt3(狀態 = 執行)- dt1(狀態 = 初始化)> operation3

對於每個任務,對應相同的id,必須執行這些操作,並且必須在結果之后將它們分組(執行結果的平均值)在包含相同名稱的任務中。

對於示例表中的行,結果應該是:

    +----------+-----------------+-----------------+------------------+
    | taskName |  avg_operation1 |  avg_operation2 |  avg_operation3  |
    +----------+-----------------+-----------------+------------------+
    |    T10   |         6       |         6       |         12       |
    |    T20   |         4       |         4       |          8       |
    |    T30   |         4       |         4       |          8       |
    +----------+-----------------+-----------------+------------------+

以我所擁有的知識,我想不出一種方法來做到這一點。 如果有人能給我一些路要走。

試試這個 - 也不確定datediff會根據日期格式而有所不同
考慮到以下幾點:

Date1 = State_Reached  
Date2 = State_Loaded  
Date3 = State_Completed  

詢問

SELECT ID, Agg_Table.Task, AVG(Agg_Table.Op_1) as Avg_Op1, AVG(Agg_Table.Op_2) as Avg_Op2, AVG(Agg_Table.Op_3) as Avg_Op3
FROM
 (SELECT
   Task,
   DATEDIFF(IF(State='Ready', State_Loaded, NULL), IF(State='Initialized', State_Reached, NULL)) as Op_1,
   DATEDIFF(IF(State='Executed', State_Completed, NULL), IF(State='Ready', State_Loaded, NULL)) as Op_2,
   DATEDIFF(IF(State='Executed', State_Completed, NULL), IF(State='Initialized', State_Reached, NULL)) as Op_3
  FROM Table_Name 
 ) as Agg_Table
GROUP BY ID, Agg_Table.Task

也為將來,可能有助於規范此表。 祝你好運!

玩這個:

select s1.taskName, avg(s1.op1), avg(s1.op2), avg(s1.op3) from
  (select taskName, if(state = 'ready', dt2-d1, NULL) as op1, if(state = 'executed', dt3-d2, NULL) as op2, if(state = 'executed', dt3-d1, NULL) as op3
  from funkyfile
  order by taskName, id) as s1
group by s1.taskName;

語法可能關閉,快速下降和骯臟。 沒有測試。 一般建議使用子查詢來准備數據,然后處理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM