返回所有组值除以组

时间:2018-09-18 14:56:34

标签: mysql

我有一个查询

SELECT GROUP, VALUE, UNIXTIME FROM TABLE1

返回一个如下所示的表:

GROUP    VALUE    UNIXTIME
A        866      1522540800
A        123      1525132800
A        100      1527811200
A        85       1530403200
A        77       1533081600
A        65       1535760000
B        376      1522540800
B        66       1525132800
B        45       1527811200
B        58       1530403200
B        42       1533081600
C        481      1522540800
C        68       1525132800
C        77       1527811200
C        50       1530403200
D        792      1522540800
D        126      1525132800
D        84       1527811200
E        1297     1522540800
E        203      1525132800
F        882      1522540800

如何获得返回相同结果的结果,但是每一行除以其所属组中的第一个值。

例如

上的VALUE
  • 第1行应为866/866 = 1
  • 第2行应为123/866 = 0.142
  • 第3行= 100/866 = 0.115
  • 第7行(B组的第一行)的值应为376/376 = 1
  • 第8行应为66/376 = 0.176,等等

2 个答案:

答案 0 :(得分:1)

尝试以下操作(适用于所有版本的MySQL,尤其是<8.0 ):

SELECT t3.*, t3.VALUE / t2.FIRST_VALUE AS RATIO 
FROM TABLE1 AS t3 
INNER JOIN (SELECT t1.GROUP, 
                   t1.VALUE AS FIRST_VALUE 
            FROM TABLE1 AS t1 
            WHERE t1.UNIXTIME = (SELECT MIN(UNIXTIME) 
                                 FROM TABLE1 AS t4 
                                 WHERE t4.GROUP = t1.GROUP) 
            GROUP BY t1.GROUP) AS t2 ON t2.GROUP = t3.GROUP 

使用GROUP_CONCAT和字符串操作的另一种可能的解决方案是:

SELECT t3.*, t3.VALUE / t2.FIRST_VALUE AS RATIO 
FROM TABLE1 AS t3 
INNER JOIN (SELECT t1.GROUP, 
                   CAST(SUBSTRING_INDEX(GROUP_CONCAT(DISTINCT t1.VALUE ORDER BY t1.UNIXTIME ASC SEPARATOR ','), ',', 1) AS UNSIGNED) AS FIRST_VALUE
            FROM TABLE1 AS t1 
            GROUP BY t1.GROUP) AS t2 ON t2.GROUP = t3.GROUP 

注意: You might need to increase the group_concat_max_len if you have more values in a particular group

答案 1 :(得分:1)

请考虑以下内容...

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(group_id INT NOT NULL
,unixtime INT NOT NULL
,value INT NOT NULL
,PRIMARY KEY(group_id,unixtime)
);

INSERT INTO my_table VALUES
(1 ,  1522540800 ,    866),
(1 ,  1525132800 ,    123),
(1 ,  1527811200 ,    100),
(1 ,  1530403200 ,     85),
(1 ,  1533081600 ,     77),
(1 ,  1535760000 ,     65),
(2 ,  1522540800 ,    376),
(2 ,  1525132800 ,     66),
(2 ,  1527811200 ,     45),
(2 ,  1530403200 ,     58),
(2 ,  1533081600 ,     42),
(3 ,  1522540800 ,    481),
(3 ,  1525132800 ,     68),
(3 ,  1527811200 ,     77),
(3 ,  1530403200 ,     50),
(4 ,  1522540800 ,    792),
(4 ,  1525132800 ,    126),
(4 ,  1527811200 ,     84),
(5 ,  1522540800 ,   1297),
(5 ,  1525132800 ,    203),
(6 ,  1522540800 ,    882);

SELECT x.*
     , value/CASE WHEN @prev = group_id THEN @val:=@val ELSE @val:=value END val
     , @prev:=group_id 
  FROM my_table x
     ,(SELECT @prev:=null,@val:=0) vars 
 ORDER 
    BY group_id
     , unixtime;
+----------+------------+-------+--------+-----------------+
| group_id | unixtime   | value | val    | @prev:=group_id |
+----------+------------+-------+--------+-----------------+
|        1 | 1522540800 |   866 | 1.0000 |               1 |
|        1 | 1525132800 |   123 | 0.1420 |               1 |
|        1 | 1527811200 |   100 | 0.1155 |               1 |
|        1 | 1530403200 |    85 | 0.0982 |               1 |
|        1 | 1533081600 |    77 | 0.0889 |               1 |
|        1 | 1535760000 |    65 | 0.0751 |               1 |
|        2 | 1522540800 |   376 | 1.0000 |               2 |
|        2 | 1525132800 |    66 | 0.1755 |               2 |
|        2 | 1527811200 |    45 | 0.1197 |               2 |
|        2 | 1530403200 |    58 | 0.1543 |               2 |
|        2 | 1533081600 |    42 | 0.1117 |               2 |
|        3 | 1522540800 |   481 | 1.0000 |               3 |
|        3 | 1525132800 |    68 | 0.1414 |               3 |
|        3 | 1527811200 |    77 | 0.1601 |               3 |
|        3 | 1530403200 |    50 | 0.1040 |               3 |
|        4 | 1522540800 |   792 | 1.0000 |               4 |
|        4 | 1525132800 |   126 | 0.1591 |               4 |
|        4 | 1527811200 |    84 | 0.1061 |               4 |
|        5 | 1522540800 |  1297 | 1.0000 |               5 |
|        5 | 1525132800 |   203 | 0.1565 |               5 |
|        6 | 1522540800 |   882 | 1.0000 |               6 |
+----------+------------+-------+--------+-----------------+
21 rows in set (0.00 sec)