5 日間のデータ (日はルーチンの引数) から 1 日の各分ごとの平均値を計算し、結果を別のテーブルに挿入する SQL ルーチンを作成しました。かなり長いので、最適化する方法があるかどうか疑問に思っていました。
平均を計算するために必要な値はすべて同じテーブルSiteReadingにあるため、同じ分の5つの値を取得しますが、異なる日からそれらの日のテーブルのサブセットに参加して、時間と分が一致し、次に値は同じ行になります。次に、各行に 5 つの値を追加し、そこから新しいテーブルを作成して、それらの平均を格納するベースライン テーブルに挿入します。
ルーチンは次のとおりです。
CREATE PROCEDURE 'calc_baseline` (IN `input_site_id` int, IN `day1` varchar(12), IN `day2` varchar(12), IN `day3` varchar(12), IN `day4` varchar(12), IN `day5` varchar(12))
BEGIN
insert into Baseline
SELECT
site_id,
contract_id,
temp_time as timestamp,
(sr1value + sr2value + sr3value + sr4value + sr5value) / 5 as value,
programme
FROM
(SELECT
distinct concat(cast(hour(temp_time) as char), ':', cast(minute(temp_time) as char)) as hourminute,
SR.site_id as site_id,
value as sr1value,
temp_time,
S.contract_id as contract_id,
programme
FROM
SiteReading SR
join Site S ON SR.site_id = S.site_id
join Contract C ON S.contract_id = C.contract_id
where
temp_time like 'day1%'
and SR.site_id = input_site_id) sr1
join
(SELECT
concat(cast(hour(temp_time) as char), ':', cast(minute(temp_time) as char)) as hourminute,
value as sr2value
FROM
SiteReading
where
temp_time like 'day2%'
and site_id = input_site_id) sr2 ON sr1.hourminute = sr2.hourminute
join
(SELECT
concat(cast(hour(temp_time) as char), ':', cast(minute(temp_time) as char)) as hourminute,
value as sr3value
FROM
SiteReading
where
temp_time like 'day3%'
and site_id = input_site_id) sr3 ON sr1.hourminute = sr3.hourminute
join
(SELECT
concat(cast(hour(temp_time) as char), ':', cast(minute(temp_time) as char)) as hourminute,
value as sr4value
FROM
SiteReading
where
temp_time like 'day4%'
and site_id = input_site_id) sr4 ON sr1.hourminute = sr4.hourminute
join
(SELECT
concat(cast(hour(temp_time) as char), ':', cast(minute(temp_time) as char)) as hourminute,
value as sr5value
FROM
SiteReading
where
temp_time like 'day5%'
and site_id = input_site_id) sr5 ON sr1.hourminute = sr5.hourminute
limit 1440;
END//
DELIMITER ;
読み取りおよび書き込みに関連するテーブルは次のとおりです。
- サイトリーディング:
CREATE TABLE `SiteReading` (
`site_id` int(11) NOT NULL,
`contract_id` int(11) DEFAULT NULL,
`temp_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`value` int(11) NOT NULL,
PRIMARY KEY (`site_id`,`temp_time`),
KEY `site_id` (`site_id`),
KEY `contract_id` (`contract_id`),
CONSTRAINT `SiteReading_ibfk_1` FOREIGN KEY (`site_id`) REFERENCES `Site` (`site_id`),
CONSTRAINT `SiteReading_ibfk_3` FOREIGN KEY (`contract_id`) REFERENCES `Contract` (`contract_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8$$
- ベースライン:
CREATE TABLE `Baseline` (
`site_id` int(11) NOT NULL,
`contract_id` int(11) NOT NULL,
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`value` int(11) NOT NULL,
`programme` int(11) NOT NULL,
PRIMARY KEY (`site_id`,`timestamp`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8$$
各行で同じベースラインに格納する追加の値 (site_id、contract_id、programme) を取得する必要があるため、別の方法で挿入ステートメントを実行する必要があるのではないかと考えていました。問題は、ベースライン テーブルのすべての列を null にすることはできないということです。
誰かがこの手順について他のコメントを持っているかもしれません.ON DUPLICATE KEY UPDATEやその他のルーチン関連のものなど、このルーチンに他のパラメータを定義する必要がありますか?
ありがとう。