Korte en eenvoudige vragen krijgen doorgaans meer aandacht dan lange/complexe. Dit is niet omdat we geen antwoord kunnen geven, maar met zoveel vragen en zo weinig vrijwilligerstijd om te geven, is het moeilijk om de tijd te rechtvaardigen om grote vragen te lezen.
Maar ik denk dat je basisvereiste niet zo ingewikkeld is. U wilt een manier om rijen op te halen die binnen een tijdbereik vallen OF, indien niet in dat bereik, de rijen die het dichtst bij dat bereik liggen.
In databases die ROW_NUMBER() OVER() ondersteunen is dit vrij eenvoudig (en MySQL 8.x is gepland om dit te ondersteunen), maar tot die tijd kun je om row_number() te emuleren variabelen en een geordende subquery gebruiken.
U kunt deze oplossing hier uitproberen op SQL Fiddle
MySQL 5.6 Schema-instellingen :
CREATE TABLE `ponumber` (
`TimeStr` datetime NOT NULL,
`Value` int(11) NOT NULL,
UNIQUE KEY `uk_Times` (`TimeStr`));
INSERT INTO `PONumber` (`TimeStr`,`Value`) VALUES ('2017-09-28 10:47:55',0);
INSERT INTO `PONumber` (`TimeStr`,`Value`) VALUES ('2017-09-28 06:26:07',1217911);
INSERT INTO `PONumber` (`TimeStr`,`Value`) VALUES ('2017-09-28 05:24:18',1217906);
CREATE TABLE `batch_number` (
`TimeStr` datetime NOT NULL,
`Value` int(11) NOT NULL,
UNIQUE KEY `uk_Times` (`TimeStr`));
INSERT INTO `batch_number` (`TimeStr`,`Value`) VALUES ('2017-09-29 12:46:18',5522);
INSERT INTO `batch_number` (`TimeStr`,`Value`) VALUES ('2017-09-29 12:25:33',5521);
INSERT INTO `batch_number` (`TimeStr`,`Value`) VALUES ('2017-09-29 11:44:45',5520);
INSERT INTO `batch_number` (`TimeStr`,`Value`) VALUES ('2017-09-28 06:26:05',5519);
INSERT INTO `batch_number` (`TimeStr`,`Value`) VALUES ('2017-09-28 05:22:58',5518);
CREATE TABLE `batchweight` (
`TimeStr` datetime NOT NULL,
`Value` int(11) NOT NULL,
UNIQUE KEY `uk_Times` (`TimeStr`));
INSERT INTO `batchweight` (`TimeStr`,`Value`) VALUES ('2017-09-29 12:46:19',38985);
INSERT INTO `batchweight` (`TimeStr`,`Value`) VALUES ('2017-09-28 06:26:07',38985);
INSERT INTO `batchweight` (`TimeStr`,`Value`) VALUES ('2017-09-28 05:23:03',31002);
Zoekopdracht :
SET @bStartTime := '2017-09-29 11:10:00'
SET @bEndTime := '2017-09-29 12:48:00'
SELECT
SrcTable, TimeStr, Value
FROM (
SELECT
@row_num :=IF( @prev_value=u.SrcTable, @row_num + 1 ,1) AS RowNumber
, u.*
, @prev_value := u.SrcTable
FROM (
select 'ponumber' SrcTable , TimeStr, `Value`
from ponumber
union all
select 'batch_number' SrcTable , TimeStr, `Value`
from batch_number
union all
select 'batchweight' SrcTable , TimeStr, `Value`
from batchweight
) u
CROSS JOIN (SELECT @row_num := 1, @prev_value :='') vars
ORDER BY SrcTable, TimeStr DESC
) d
WHERE (d.TimeStr between @bStartTime and @bEndTime)
OR (TimeStr < @bStartTime AND RowNumber = 1)
Dus wat dit doet, is een "Rijnummer" berekenen dat begint bij 1 voor de meest recente rij voor elke brontabel. Vervolgens wordt deze afgeleide tabel gefilterd op het tijdbereik of op het rijnummer, indien niet binnen het tijdbereik.
Merk ook op dat ik NIET gebruikt UNION
maar hebben in plaats daarvan UNION ALL
. gebruikt . Er is een groot verschil in prestaties en zou moeten leren om elk naar behoefte te gebruiken. Bij gebruik van UNION
gebruik niet ook select distinct
omdat je gewoon moeite verspilt.
| SrcTable | TimeStr | Value |
|--------------|----------------------|-------|
| batchweight | 2017-09-29T12:46:19Z | 38985 |
| batch_number | 2017-09-29T12:46:18Z | 5522 |
| batch_number | 2017-09-29T12:25:33Z | 5521 |
| batch_number | 2017-09-29T11:44:45Z | 5520 |
| ponumber | 2017-09-28T10:47:55Z | 0 |