从多个列值计算百分比

时间:2019-12-24 04:16:17

标签: mysql

我想找到MySql查询,以根据不同列上的值计算完成的工作百分比,以前我是在Microsoft Excel中使用countif做到的,但是现在我想在mysql上创建相同的表。

这是我当前的表格

Parts Already Build : 
------------------------------------------------------------------
| id | Front   |  Rear   |  Left   | Right   |  Up     |  Down   |
__________________________________________________________________

| 01 | Done    |  Done   | Done    | Done    | Done    |  Done   |
------------------------------------------------------------------
| 02 | Done    |  Done   | Done    | Done    | No Need | No Need |
------------------------------------------------------------------
| 03 | Done    | Ongoing | Ongoing | Done    | Done    | Not Yet | 
------------------------------------------------------------------
| 04 | Not Yet | Not Yet | Not Yet | Not Yet | Not Yet | Not Yet |
------------------------------------------------------------------

预期结果

Parts Already Build : 
--------------------------------------------------------------------------------
| id | Front   |  Rear   |  Left   | Right   |  Up     |  Down   |   %   |  Status  |
________________________________________________________________________________

| 01 | Done    |  Done   | Done    | Done    | Done    |  Done   |  100  | Complete |
--------------------------------------------------------------------------------
| 02 | Done    |  Done   | Done    | Done    | No Need | No Need |  100  | Complete |
--------------------------------------------------------------------------------
| 03 | Done    | Ongoing | Ongoing | Done    | Done    | Not Yet |   50  | Ongoing  |
--------------------------------------------------------------------------------
| 04 | Not Yet | Not Yet | Not Yet | Not Yet | Not Yet | Not Yet |    0  | Not Yet  |
--------------------------------------------------------------------------------

注意:

  1. 如果所有过程都已完成,或者在该6列中有6个“ done”值,则%column = 100
  2. 如果值为“ No Need”,则将其计为“ Done”。
  3. 如果不是所有过程都已完成/没有任何过程完成,则该表将仅计算有多少“完成”或“不需要”值,并将其转换为%列中的百分比(3/6进程为“完成” = 50%)
  4. 如果%为= 100%,则“状态”列=已完成/如果= %% =尚未/如果其他(1%-99%=正在进行)

当前查询:

SELECT
front,
rear,
left,
right,
up,
down,
_________________ AS %,
_________________ AS Status
FROM process

3 个答案:

答案 0 :(得分:1)

对于给定的表结构,您需要将状态为DoneNo Need的所有情况加起来,以获得完整性的值,然后可以将其用于生成{{ 1}}和%列:

status

输出

SELECT `Front`, `Rear`, `Left`, `Right`, `Up`, `Down`,
        complete * 100 / 6 AS percent,
        CASE complete WHEN 6 THEN 'Complete'
                      WHEN 0 THEN 'Not Yet'
                      ELSE 'Ongoing'
        END AS status
FROM (SELECT *,
             0 + (Front = 'Done' OR Front = 'No Need')
               + (Rear  = 'Done' OR Rear = 'No Need')
               + (`Left`  = 'Done' OR `Left` = 'No Need')
               + (`Right` = 'Done' OR `Right` = 'No Need')
               + (Up    = 'Done' OR Up = 'No Need')
               + (Down  = 'Done' OR Down = 'No Need') AS complete
      FROM process) p

Demo on dbfiddle

答案 1 :(得分:0)

老实说,您应该首先修复数据模型。您应该只具有两列列,而不是六列不同的方向,一列代表方向,另一列代表值。考虑以下版本的数据:

id | direction | status
1  | Front     | Done
1  | Rear      | Done
1  | Left      | Done
1  | Right     | Done
1  | Up        | Done
1  | Down      | Done
2  | Front     | Done
2  | Rear      | Done
2  | Left      | Done
2  | Right     | Done
2  | Up        | No Need
2  | Down      | No Need
...

使用此归一化版本的数据,我们可以轻松地编写以下查询:

SELECT
    id,
    100.0 * AVG(status IN ('Done', 'No Need')) AS pct,
    CASE WHEN SUM(status NOT IN ('Done', 'No Need')) = 0 THEN 'Complete'
         WHEN SUM(status = 'Ongoing') > 0 THEN 'Ongoing'
         WHEN SUM(status = 'Not Yet') = COUNT(*) THEN 'Not Yet'
         ELSE 'Unknown' END AS status
FROM yourNewTable
GROUP BY
    id;

screen capture of demo below

Demo

答案 2 :(得分:0)

您可以尝试:

SELECT front, rear, left_col, right_col, up, down,
FLOOR((IF(front = 'Done' OR front = 'No Need', 1, 0) + IF(rear= 'Done' OR rear = 'No Need', 1, 0) + IF(left_col = 'Done' OR left_col = 'No Need', 1, 0) + IF(right_col = 'Done' OR right_col = 'No Need', 1, 0) + IF(up = 'Done' OR up = 'No Need', 1, 0) + IF(down = 'Done' OR down = 'No Need', 1, 0))/6 * 100) AS Percent,
CASE WHEN FLOOR((IF(front = 'Done' OR front = 'No Need', 1, 0) + IF(rear= 'Done' OR rear = 'No Need', 1, 0) + IF(left_col = 'Done' OR left_col = 'No Need', 1, 0) + IF(right_col = 'Done' OR right_col = 'No Need', 1, 0) + IF(up = 'Done' OR up = 'No Need', 1, 0) + IF(down = 'Done' OR down = 'No Need', 1, 0))/6 * 100) = 100 THEN 'Complete'
     WHEN FLOOR((IF(front = 'Done' OR front = 'No Need', 1, 0) + IF(rear= 'Done' OR rear = 'No Need', 1, 0) + IF(left_col = 'Done' OR left_col = 'No Need', 1, 0) + IF(right_col = 'Done' OR right_col = 'No Need', 1, 0) + IF(up = 'Done' OR up = 'No Need', 1, 0) + IF(down = 'Done' OR down = 'No Need', 1, 0))/6 * 100) = 0 THEN 'Not Yet'
     ELSE 'Ongoing' END AS Status
     FROM Test

这是demo

enter image description here