Out of "historic" reason i have following table:
CREATE TABLE IF NOT EXISTS `measurement`
(
`measureID` int NOT NULL AUTO_INCREMENT ,
`terraID` int NOT NULL ,
`pinID` int NOT NULL ,
`time` timestamp NOT NULL ,
`value` float NULL ,
`temperature` boolean NOT NULL ,
PRIMARY KEY (`measureID`),
KEY `measure_terraID_FK` (`terraID`),
KEY `measure_pinID_FK` (`pinID`),
CONSTRAINT `measure_terraID_reference` FOREIGN KEY `measure_terraID_FK` (`terraID`) REFERENCES `terrarium` (`terraID`),
CONSTRAINT `measure_pinID_reference` FOREIGN KEY `measure_pinID_FK` (`pinID`) REFERENCES `pins` (`pinID`)
) ENGINE=INNODB COLLATE=utf8mb4_unicode_ci;
| measureID | terraID | pinID | time | value | temperature |
|:----------|---------|-------|---------------------|--------|------------:|
| 1 | 1 | 9 | 2020-04-10 13:00:01 | 34.3 | 0 |
| 2 | 1 | 9 | 2020-04-10 13:00:01 | 26.5 | 1 |
| 3 | 2 | 10 | 2020-04-10 13:00:01 | 35.1 | 0 |
| 4 | 2 | 10 | 2020-04-10 13:00:01 | 32.9 | 1 |
| 5 | 1 | 9 | 2020-04-10 13:05:01 | 34.4 | 0 |
| 6 | 1 | 9 | 2020-04-10 13:05:01 | 26.6 | 1 |
| 7 | 2 | 10 | 2020-04-10 13:05:01 | 35 | 0 |
| 8 | 2 | 10 | 2020-04-10 13:05:01 | 33 | 1 |
[...]
| 38087 | 2 | 10 | 2020-08-31 12:50:02 | 35.9 | 0 |
| 38088 | 2 | 10 | 2020-08-31 12:50:02 | 35 | 1 |
| 38089 | 1 | 11 | 2020-08-31 12:50:02 | 25.187 | 1 |
| 38090 | 2 | 12 | 2020-08-31 12:50:02 | 28.312 | 1 |
| 38091 | 2 | 10 | 2020-08-31 12:55:01 | 35.8 | 0 |
| 38092 | 2 | 10 | 2020-08-31 12:55:01 | 35 | 1 |
| 38093 | 1 | 11 | 2020-08-31 12:55:01 | 25.25 | 1 |
| 38094 | 2 | 12 | 2020-08-31 12:55:01 | 28.375 | 1 |
and want that to be inserted into a new table, based on time and pinID, so that the final table looks like that:
CREATE TABLE IF NOT EXISTS `measurement`
(
`measureID` int NOT NULL AUTO_INCREMENT ,
`terraID` int NOT NULL ,
`pinID` int NOT NULL ,
`time` timestamp NOT NULL ,
`temperature` float NULL ,
`humidity` float NULL ,
PRIMARY KEY (`measureID`),
KEY `measure_terraID_FK` (`terraID`),
KEY `measure_pinID_FK` (`pinID`),
CONSTRAINT `measure_terraID_reference` FOREIGN KEY `measure_terraID_FK` (`terraID`) REFERENCES `terrarium` (`terraID`),
CONSTRAINT `measure_pinID_reference` FOREIGN KEY `measure_pinID_FK` (`pinID`) REFERENCES `pins` (`pinID`)
) ENGINE=INNODB COLLATE=utf8mb4_unicode_ci;
| measureID | terraID | pinID | time | temperature | humidity |
|:----------|---------|-------|---------------------|--------------|---------:|
| 2 | 1 | 9 | 2020-04-10 13:00:01 | 26.5 | 34.3 |
| 4 | 2 | 10 | 2020-04-10 13:00:01 | 32.9 | 35.1 |
| 6 | 1 | 9 | 2020-04-10 13:05:01 | 26.6 | 34.4 |
| 8 | 2 | 10 | 2020-04-10 13:05:01 | 33 | 35 |
[...]
| 38088 | 2 | 10 | 2020-08-31 12:50:02 | 35 | 35.9 |
| 38089 | 1 | 11 | 2020-08-31 12:50:02 | 25.187 | NULL |
| 38090 | 2 | 12 | 2020-08-31 12:50:02 | 28.312 | NULL |
| 38092 | 2 | 10 | 2020-08-31 12:55:01 | 35 | 35.8 |
| 38093 | 1 | 11 | 2020-08-31 12:55:01 | 25.25 | NULL |
| 38094 | 2 | 12 | 2020-08-31 12:55:01 | 28.375 | NULL |
My SQL Version is mariadb-10.3
I don't want to lose any values and I don't care for the temperature column, because it's an old identifier in how to read the value. But I want to modify all old entries to be transformed to the new structure. But you can use it in IF(temperature=1, value, NULL) as temperature, IF(temperature=0, value, '') as humidity or somewhat.
The terraID and pinID are keyed to other tables and not all sensors deliver temperature and humidity.
I have no luck with some insert into select subquerie magic... maybe I'm too dumb to wrap my head around the problem.
Can you possibly lead me to the correct function. It's just a once-triggered manual job.
If I follow you correctly, you can use conditional aggregation:
select
min(measureID),
terraID,
pinID,
time,
max(case when temperature = 1 then value end) value,
max(case when temperature = 0 then value end) humidity
from mytable
group by terraID, pinID, time
order by min(measureID)
If needed, you can easily turn this to an insert
query (using insert... select...
) or even to a create table
statement ( create table newtable as...
).
measureID | terraID | pinID | time | value | humidity --------: | ------: | ----: | :------------------ | -----: | -------: 2 | 1 | 9 | 2020-04-10 13:00:01 | 26.500 | 34.300 4 | 2 | 10 | 2020-04-10 13:00:01 | 32.900 | 35.100 6 | 1 | 9 | 2020-04-10 13:05:01 | 26.600 | 34.400 8 | 2 | 10 | 2020-04-10 13:05:01 | 33.000 | 35.000 38088 | 2 | 10 | 2020-08-31 12:50:02 | 35.000 | 35.900 38089 | 1 | 11 | 2020-08-31 12:50:02 | 25.187 | null 38090 | 2 | 12 | 2020-08-31 12:50:02 | 28.312 | null 38092 | 2 | 10 | 2020-08-31 12:55:01 | 35.000 | 35.800 38093 | 1 | 11 | 2020-08-31 12:55:01 | 25.250 | null 38094 | 2 | 12 | 2020-08-31 12:55:01 | 28.375 | null
Use LEAD()
window function:
INSERT INTO new_measurement(measureID, terraID, pinID, time, temperature, humidity)
SELECT measureID, terraID, pinID, time,
CASE temperature WHEN 1 THEN value END,
value
FROM (
SELECT *,
LEAD(terraID) OVER (ORDER BY time DESC) next_terraID,
LEAD(pinID) OVER (ORDER BY time DESC) next_pinID
FROM measurement
) t
WHERE terraID <> next_terraID OR pinID <> next_pinID
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.