값이 변경된 값 및 열을 선택하십시오.
값이 1씩 변경될 때마다 1개의 행을 기록하는 히스토리가 있습니다.따라서 각 행에는 항상 이전 행에서 변경된 값이 1개만 있어야 합니다.
제 테이블은 이렇게 생겼어요.(컬럼이 5개가 넘고 일반 이름은 없습니다.이러한 컬럼 이름은 프로젝트별로 변경됩니다.열 이름 하드코딩을 피하고 싶습니다.)
INDEX|Column1|Column2|Column3|Column4|Column5|TimeStamp
1 | 0| 0| 0| 0| 0|2017-03-28 13:00:00
2 | 0| 0| 0| 1| 0|2017-03-28 14:00:00
3 | 2| 0| 0| 1| 0|2017-03-28 15:00:00
4 | 3| 0| 0| 1| 0|2017-03-28 16:00:00
5 | 3| 22| 0| 1| 0|2017-03-28 17:00:00
6 | 3| 22| 6| 1| 0|2017-03-28 18:00:00
내가 보고서에 넣고 싶은 결과.
Name |NewValue|PreviousValue|TimeStamp
Column4| 1| 0|2017-03-28 14:00:00
Column1| 2| 0|2017-03-28 15:00:00
Column1| 3| 2|2017-03-28 16:00:00
Column2| 22| 0|2017-03-28 17:00:00
Column3| 6| 0|2017-03-28 18:00:00
이를 실현하는 가장 좋은 방법은 무엇일까요?
MariaDB 10.1.22를 사용하고 있습니다.
정적 SQL 사용:
이것이 당신이 원하는 기본 코드입니다.하지만 모든 게 하드코드로 되어 있어요이는 "동적인 SQL" 없이는 피할 수 없습니다.
SELECT
CASE
WHEN t1.Column1 <> t2.Column1 THEN 'Column1'
WHEN t1.Column2 <> t2.Column2 THEN 'Column2'
WHEN t1.Column3 <> t2.Column3 THEN 'Column3'
WHEN t1.Column4 <> t2.Column4 THEN 'Column4'
WHEN t1.Column5 <> t2.Column5 THEN 'Column5'
END as Name,
CASE
WHEN t1.Column1 <> t2.Column1 THEN t2.Column1
WHEN t1.Column2 <> t2.Column2 THEN t2.Column2
WHEN t1.Column3 <> t2.Column3 THEN t2.Column3
WHEN t1.Column4 <> t2.Column4 THEN t2.Column4
WHEN t1.Column5 <> t2.Column5 THEN t2.Column5
END as NewValue,
CASE
WHEN t1.Column1 <> t2.Column1 THEN t1.Column1
WHEN t1.Column2 <> t2.Column2 THEN t1.Column2
WHEN t1.Column3 <> t2.Column3 THEN t1.Column3
WHEN t1.Column4 <> t2.Column4 THEN t1.Column4
WHEN t1.Column5 <> t2.Column5 THEN t1.Column5
END as PreviousValue,
t2.TimeStamp
FROM
MyTable t1
JOIN MyTable t2
ON t2.Index = t1.Index + 1
열이 가능한 경우NULL
이전이나 이후 중 어느 쪽이든<>
를 참조해 주세요.
Dynamic SQL 사용:
열 이름을 하드 코드하는 것이 아니라 열 데이터를 추출하여 위와 같은 코드를 생성할 수 있습니다.information_schema
를 참조할 수 있습니다.설정@tablename
variable은 처리할 테이블의 이름으로, 이 코드는 변수를 설정합니다.@sql
위의 코드와 동등한 코드를 유지합니다.사용한 적이 있다\n
새 행을 추가하여 생성된 코드의 형식을 개선합니다.
-- Avoids the GROUP_CONCAT truncating the code we're building
SET SESSION GROUP_CONCAT_MAX_LEN=65535;
-- Specify your target table here
SELECT @tablename := 'MyTable';
SELECT @sql := GROUP_CONCAT(theCode SEPARATOR '')
FROM
(
-- theOrderBy is for keeping the various parts of this code in the correct sequence
-- SELECT plus the opening of the first CASE statement
SELECT 0 theOrderBy, 'SELECT\nCASE\n' theCode
UNION ALL
-- Generates the inner part first CASE statement
SELECT 1, CONCAT(' WHEN t1.',Column_Name,' <> t2.',Column_Name,' THEN ''', Column_Name,'''','\n')
FROM `information_schema`.`Columns`
WHERE table_name like @tablename
AND Column_Name NOT IN ('Index','Timestamp')
UNION ALL
-- Generates the end of the first CASE (and it's alias) and the beginning of the second one
SELECT 2, 'END as Name,\nCASE\n'
UNION ALL
-- Generates the inner part second CASE statement
SELECT 3, CONCAT(' WHEN t1.',Column_Name,' <> t2.',Column_Name,' THEN t2.', Column_Name, '\n')
from `information_schema`.`Columns`
WHERE table_name LIKE @tablename
AND Column_Name NOT IN ('Index','Timestamp')
UNION ALL
-- Generates the end of the second CASE (and it's alias) and the beginning of the third one
SELECT 4, 'END as NewValue,\nCASE\n'
UNION ALL
-- Generates the inner part third CASE statement
SELECT 5, CONCAT(' WHEN t1.',Column_Name,' <> t2.',Column_Name,' THEN t1.', Column_Name, '\n')
FROM `information_schema`.`Columns`
WHERE table_name like @tablename
AND Column_Name NOT IN ('Index','Timestamp')
UNION ALL
-- Generates the end of the final CASE statement plus the FROM clause
SELECT 6, CONCAT('END as PreviousValue,\nt2.Timestamp\nFROM\n ',@tablename, ' t1\n JOIN ',@tablename, ' t2 ON\n t2.Index = t1.Index + 1')
ORDER BY theOrderBy
) as sub;
SELECT @sql;
변수에 표시된 내용이 만족스러운 경우 마지막 줄을 다음과 같이 대체하여 다시 실행할 수 있습니다.
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
이 코드의 실행 가능성은 타겟 테이블에 대해 동일한 필수 구조를 가지고 있는지 여부에 따라 크게 좌우됩니다.즉, 순차적으로 증가하고 있습니다.Index
필드 및 aTimestamp
. "Static" 코드와 마찬가지로 이 코드도<>
모든 비교에도 불구하고, 따라서 효과적으로 그 필드가 그렇지 않을 것이라고 가정합니다.NULL
각 변경 전 또는 변경 후.
만약 그 전제조건이 성립되지 않는다면, 당신은 조정을 해야 할 것이다.도움이 필요하시면 말씀하세요.
SELECT 'Column5', column5, max(timestamp) from mytable where column5 <> 0 group by column5
Union
SELECT 'Column4', column4, max(timestamp) from mytable where column4 <> 0 group by column4
Union
SELECT 'Column3', column3, max(timestamp) from mytable where column3 <> 0 group by column3
Union
SELECT 'Column2', column2, max(timestamp) from mytable where column2 <> 0 group by column2
Union
SELECT 'Column1', column1, max(timestamp) from mytable where column1 <> 0 group by column1
언급URL : https://stackoverflow.com/questions/44376361/select-value-and-column-that-value-have-changed
'itsource' 카테고리의 다른 글
JavaScript에서 어레이를 비우려면 어떻게 해야 합니까? (0) | 2022.09.04 |
---|---|
사전 키를 사용할 수 없는 경우 기본값 반환 (0) | 2022.09.04 |
프라이머리 키를 1000부터 시작하는 방법 (0) | 2022.09.04 |
jQuery UI 대화상자 - 닫기 아이콘 누락 (0) | 2022.09.04 |
Firebase Error:함수 쿼리여기서()이 유효하지 않은 데이터로 호출되었습니다.지원되지 않는 필드 값: 정의되지 않음 (0) | 2022.09.04 |