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等
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:)谢谢您的帮助。两种解决方案都很有效,因此我将另一个方案标记为第一个答案,似乎是最公平的。。