按 mysql 中的参考值划分行
Dividing a row by reference value in mysql
请帮助我。
原始数据如下:
uid | id | value |
1 | a | 389 |
2 | b | 201 |
3 | c | 170 |
if....当参考值为'200'时
怎么弄成这样的?
mysql..
no| uid | id | value | cut
1 | 1 | a | 200 | 200
2 | 1 | a | 189 | 200
3 | 2 | b | 200 | 200
4 | 2 | b | 1 | 200
5 | 3 | c | 170 | 200
帮帮我!!!
考虑编写一个存储过程,而不是完全在 SQL 中或仅在 select table 中的行中执行所有操作,并在 php 中执行以下操作:
据我了解,您正在寻找这个:
no = 1
For each row in the result set
for i = 0 to int(value/cut)
output the row with value set to cut
no += 1
output the row with value set to mod(value, cut)
no += 1
如果您使用的是 MySQL 8 或更高版本,递归 CTE 可以提供帮助:
CREATE DATABASE test;
USE test;
CREATE TABLE TestData (uid INTEGER, id VARCHAR(8), value INTEGER);
INSERT INTO TestData VALUES (1, 'a', 389);
INSERT INTO TestData VALUES (2, 'b', 201);
INSERT INTO TestData VALUES (3, 'c', 170);
INSERT INTO TestData VALUES (4, 'd', 550);
-- Set up an auto-incrementing row number
SET @row_num = 0;
WITH RECURSIVE cte (uid, id, value, remainder) AS (
-- start with a copy of the table, but adding another column for the value that is at most 200
SELECT a.uid, a.id, LEAST(a.value, 200), a.value AS "remainder" FROM TestData a
UNION
-- repeatedly select from the previous result set, meanwhile decrementing the "remainder" column
SELECT uid, id, LEAST(remainder - 200, 200), remainder - 200 FROM cte WHERE remainder > 200
)
-- select the actual data that we care about
SELECT (@row_num := @row_num + 1) AS no, uid, id, value, 200 AS "cut" FROM cte ORDER BY id, value DESC;
结果如下 table:
no | uid | id | value | cut
1 | 1 | a | 200 | 200
2 | 1 | a | 189 | 200
3 | 2 | b | 200 | 200
4 | 2 | b | 1 | 200
5 | 3 | c | 170 | 200
6 | 4 | d | 200 | 200
7 | 4 | d | 200 | 200
8 | 4 | d | 150 | 200
这个怎么样:
SET @row_num = 0;
SELECT (@row_num := @row_num + 1) AS "no",uid,id,valueA, "200" as cut FROM
(SELECT uid,id,IF(valueA/200 > 1,200,valueA) AS "valueA" FROM tableA UNION ALL
SELECT uid,id,IF(valueA/200 > 2,200,valueA-200) AS "valueA" FROM tableA UNION ALL
SELECT uid,id,IF(valueA/200 > 3,200,valueA-400) AS "valueA" FROM tableA) a
WHERE valueA > 0
ORDER BY uid,id,valueA DESC;
如果valueA除以200等于大于1,则return200,否则只returnvalueA的内容。这是 UNION ALL
查询中的第一个语法。
第二个我添加了另一个条件,好像 valueA 除以 200 不等于大于 2,它将 return valueA-200。您可以尝试执行 UNION ALL
查询以查看结果。
这不是最好的方法,我相信有更好的解决方案,但我使用这种方法让它工作。您可以将其用作临时解决方案或至少给您一些想法。
请帮助我。
原始数据如下:
uid | id | value |
1 | a | 389 |
2 | b | 201 |
3 | c | 170 |
if....当参考值为'200'时
怎么弄成这样的?
mysql..
no| uid | id | value | cut
1 | 1 | a | 200 | 200
2 | 1 | a | 189 | 200
3 | 2 | b | 200 | 200
4 | 2 | b | 1 | 200
5 | 3 | c | 170 | 200
帮帮我!!!
考虑编写一个存储过程,而不是完全在 SQL 中或仅在 select table 中的行中执行所有操作,并在 php 中执行以下操作:
据我了解,您正在寻找这个:
no = 1
For each row in the result set
for i = 0 to int(value/cut)
output the row with value set to cut
no += 1
output the row with value set to mod(value, cut)
no += 1
如果您使用的是 MySQL 8 或更高版本,递归 CTE 可以提供帮助:
CREATE DATABASE test;
USE test;
CREATE TABLE TestData (uid INTEGER, id VARCHAR(8), value INTEGER);
INSERT INTO TestData VALUES (1, 'a', 389);
INSERT INTO TestData VALUES (2, 'b', 201);
INSERT INTO TestData VALUES (3, 'c', 170);
INSERT INTO TestData VALUES (4, 'd', 550);
-- Set up an auto-incrementing row number
SET @row_num = 0;
WITH RECURSIVE cte (uid, id, value, remainder) AS (
-- start with a copy of the table, but adding another column for the value that is at most 200
SELECT a.uid, a.id, LEAST(a.value, 200), a.value AS "remainder" FROM TestData a
UNION
-- repeatedly select from the previous result set, meanwhile decrementing the "remainder" column
SELECT uid, id, LEAST(remainder - 200, 200), remainder - 200 FROM cte WHERE remainder > 200
)
-- select the actual data that we care about
SELECT (@row_num := @row_num + 1) AS no, uid, id, value, 200 AS "cut" FROM cte ORDER BY id, value DESC;
结果如下 table:
no | uid | id | value | cut
1 | 1 | a | 200 | 200
2 | 1 | a | 189 | 200
3 | 2 | b | 200 | 200
4 | 2 | b | 1 | 200
5 | 3 | c | 170 | 200
6 | 4 | d | 200 | 200
7 | 4 | d | 200 | 200
8 | 4 | d | 150 | 200
这个怎么样:
SET @row_num = 0;
SELECT (@row_num := @row_num + 1) AS "no",uid,id,valueA, "200" as cut FROM
(SELECT uid,id,IF(valueA/200 > 1,200,valueA) AS "valueA" FROM tableA UNION ALL
SELECT uid,id,IF(valueA/200 > 2,200,valueA-200) AS "valueA" FROM tableA UNION ALL
SELECT uid,id,IF(valueA/200 > 3,200,valueA-400) AS "valueA" FROM tableA) a
WHERE valueA > 0
ORDER BY uid,id,valueA DESC;
如果valueA除以200等于大于1,则return200,否则只returnvalueA的内容。这是 UNION ALL
查询中的第一个语法。
第二个我添加了另一个条件,好像 valueA 除以 200 不等于大于 2,它将 return valueA-200。您可以尝试执行 UNION ALL
查询以查看结果。
这不是最好的方法,我相信有更好的解决方案,但我使用这种方法让它工作。您可以将其用作临时解决方案或至少给您一些想法。