Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 返回所有组值除以组中的第一个值_Mysql - Fatal编程技术网

Mysql 返回所有组值除以组中的第一个值

Mysql 返回所有组值除以组中的第一个值,mysql,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

我有一个问题

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
我如何得到一个返回相同结果的结果,但是每一行都被它自己的组中的第一个值所除

举个例子,价值观

  • 第1行应为866/866=1
  • 第2行应为123/866=0.142
  • 第3行=100/866=0.115
  • 第7行(B组的第一行)上的值应为376/376=1
  • 第8行应为66/376=0.176等
尝试以下方法(适用于所有版本的MySQL,尤其是<8.0):

另一种可能的解决方案是利用
GROUP\u 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 
注意:

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

另一种可能的解决方案是利用
GROUP\u 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 

注意:

考虑以下几点

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)

考虑以下几点

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)

每组中第一个值的定义是什么?你有一个主键(id)可以根据它来定义第一个值吗?@MadhurBhaiya只是猜测一下,但我怀疑它是时间最短的一个,可以在草莓的评论中添加一个UNIXTIME/DATETIME数据类型列来标识MySQL@MadhurBhaiya中的行顺序“你有主键(id)吗?”根据可以定义的第一个值?“不仅需要一个具有自动增量选项的主键列来执行此操作。每个组中第一个值的定义是什么?你有一个主键(id)可以根据它来定义第一个值吗?@MadhurBhaiya只是猜测一下,但我怀疑它是时间最短的一个,可以在草莓的评论中添加一个UNIXTIME/DATETIME数据类型列来标识MySQL@MadhurBhaiya中的行顺序“你有主键(id)吗?”根据可以定义的第一个值?“不仅需要一个具有自动增量选项的主键列来执行此操作。我看到您使用的是
GROUP\u CONCAT
“hack”“alot”您知道默认的GROUP\u CONCAT长度为1024对吗?@RaymondNijland是的,我知道。但出于实际目的,它是有效的。反正
set group\u concat\u max\u len
可以使用“反正set group\u concat\u max\u len可以使用”我知道。。。您应该在您的帖子中说,TopicStarter很可能没有意识到这个GROUP_CONCAT限制会对实际表格数据大小造成不良结果。@RaymondNijland我添加了一个不使用GROUP_CONCAT:)谢谢您的帮助。两种解决方案都很有效,因此我将另一个方案标记为第一个答案,似乎最公平。我看到您使用了
GROUP\u CONCAT
“hack”“alot”您知道默认的GROUP\u CONCAT长度为1024,对吗?@RaymondNijland是的,我知道。但出于实际目的,它是有效的。反正
set group\u concat\u max\u len
可以使用“反正set group\u concat\u max\u len可以使用”我知道。。。您应该在您的帖子中说,TopicStarter很可能没有意识到这个GROUP_CONCAT限制会对实际表格数据大小造成不良结果。@RaymondNijland我添加了一个不使用GROUP_CONCAT:)谢谢您的帮助。两种解决方案都很有效,因此我将另一个方案标记为第一个答案,似乎是最公平的。。