Выберите столбец, в котором значение изменилось для каждой строки - PullRequest
0 голосов
/ 28 ноября 2018

Я пытаюсь извлечь данные из таблицы MySQL и вставить в другую таблицу в формате файла журнала.

допустим, у меня есть эта таблица.

TableA

+--------+----+-------+-------+-------+---------+
|UniqueID|Item|ColumnA|ColumnB|ColumnC|TimeStamp|
+--------+----+-------+-------+-------+---------+
|1       | 1  | 500   | 600   | 700   |   13:01 |
|2       | 2  |  50   |  60   |  70   |   13:03 |
|3       | 3  |  17   |  18   |  19   |   13:12 |
|4       | 1  | 501   | 600   | 700   |   13:15 |
|5       | 1  | 501   | 600   | 699   |   13:18 |
|6       | 3  |  20   |  18   |  19   |   13:22 |
|7       | 1  | 501   | 600   | 702   |   13:25 |
|8       | 2  |  50   |  66   |  70   |   13:26 |
|9       | 3  |  20   |  25   |  19   |   13:32 |
+--------+----+-------+-------+-------+---------+

У меня будет несколько таблиц с различным количеством столбцов и элементов.я не возражаю против жесткого кодирования имени таблицы и имени столбца.

Я бы хотел закончить с этой таблицей

+----+------+-------+--------+-------------+---------+
|Item|Table |Column |NewValue|PreviousValue|TimeStamp|
+----+------+-------+--------+-------------+---------+
| 1  |TableA|ColumnA| 501    | 500         | 13:15   |
| 1  |TableA|ColumnC| 699    | 700         | 13:18   |
| 3  |TableA|ColumnA|  20    |  17         | 13:22   |
| 1  |TableA|ColumnC| 699    | 702         | 13:25   |
| 2  |TableA|ColumnB|  66    |  60         | 13:26   |
| 3  |TableA|ColumnB|  25    |  18         | 13:32   |
+----+------+-------+--------+-------------+---------+

1 Ответ

0 голосов
/ 28 ноября 2018

MySQL не делает это действительно легким.Вы можете получить предыдущую запись, рассчитав предыдущую временную метку и затем присоединив ее. В MySQL 8.0 для этой цели вы можете использовать lag().

Затем вам нужно отменить эти значения.MySQL не делает это действительно простым, но вы можете использовать выражения cross join и case.Остальное - просто условная логика и фильтрация:

select item, 'TableA' as tableName, colname,
       col as newvalue, col_prev as prevvalue, timestamp
from (select t.*, c.colname,
             (case when c.colname = 'columnA' then columnA
                   when c.colname = 'columnB' then columnB
                   when c.colname = 'columnC' then columnC
              end) as col,
             (case when c.colname = 'columnA' then tprev.columnA
                   when c.colname = 'columnB' then tprev.columnB
                   when c.colname = 'columnC' then tprev.columnC
              end) as col_prev
      from (select t.*,
                   (select max(t2.timestamp)
                    from tablea t2
                    where t2.item = t.item and t2.timestamp < t.timestamp
                   ) as timestamp_prev
            from tablea t
           ) t join
           t tprev
           on t.item = tprev.item and t.timestamp_prev = tprev.timestamp cross join
           (select 'columnA' as colname union all
            select 'columnB' as colname union all
            select 'columnC' as colname
           ) c
     ) ct
where col_prev <> col;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...