Разделение строки по значению ссылки в MySQL - PullRequest
0 голосов
/ 16 января 2019

Пожалуйста, помогите мне.

Вот необработанные данные:

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

помоги мне !!!!

Ответы [ 3 ]

0 голосов
/ 16 января 2019

Если вы используете 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;

Это приводит к следующей таблице:

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
0 голосов
/ 16 января 2019

Как насчет этого:

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;

Если значение A делить на 200, равное более чем 1, возвращается 200, в противном случае возвращается только то, что находится в значении A. Это первый синтаксис среди UNION ALL запросов.

Во втором случае я добавил еще одно условие, как если бы значение A, деленное на 200, НЕ равняется более чем 2, будет возвращено значение A-200. Вы можете попытаться выполнить UNION ALL запросы, чтобы увидеть результаты.

Это не лучший способ сделать это, и я уверен, что есть лучшее решение, но я получил его, используя этот метод. Вы можете использовать это как временное решение или, по крайней мере, дать вам некоторые идеи.

0 голосов
/ 16 января 2019

Попробуйте написать хранимую процедуру вместо того, чтобы делать все это на чистом SQL, или просто выбрать строки из таблицы и сделать следующее в 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
...