Кратките и прости въпроси обикновено привличат повече внимание от дългите/сложните. Това не е защото не можем да отговорим, но с толкова много въпроси и толкова малко доброволно време е трудно да се оправдае времето за четене на големи въпроси.
Въпреки това мисля, че основното ви изискване не е толкова сложно. Искате начин да извлечете редове, които попадат в рамките на времеви диапазон ИЛИ, ако не са в този диапазон, осигурете най-близките редове до този диапазон.
В бази данни, които поддържат ROW_NUMBER() OVER() това е доста лесно (и MySQL 8.x се планира да поддържа това), но дотогава, за да емулирате row_number(), можете да използвате променливи и подредена подзаявка.
Можете да изпробвате това решение тук в SQL Fiddle
Настройка на схемата на MySQL 5.6 :
СЪЗДАВАНЕ НА ТАБЛИЦА `ponumber` ( `TimeStr` datetime НЕ НУЛВО, `Стойност` int(11) НЕ НУЛЕВО, УНИКАЛЕН КЛЮЧ `uk_Times` (`TimeStr`));ВМЪКНЕТЕ В `PONumber` (`TimeStr` ,`Стойност`) VALUES ('2017-09-28 10:47:55',0);INSERT INTO `PONumber` (`TimeStr`,`Value`) VALUES ('2017-09-28 06:26:07) ',1217911);ВЪВЕТЕ ВЪВ `PONumber` (`TimeStr`,`Value`) СТОЙНОСТИ ('2017-09-28 05:24:18',1217906);СЪЗДАДЕТЕ ТАБЛИЦА `party_number` (`TimeStr` дата и час НЕ NU `Стойност` int(11) НЕ НУЛЕВА, УНИКАЛЕН КЛЮЧ `uk_Times` (`TimeStr`));ВМЕСЕТЕ В `партиден_номер` (`TimeStr`,`Стойност`) 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 `party_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);СЪЗДАДЕТЕ ТАБЛИЦА `batchweight` (`TimeStr` datetime NOT NULL, `Value` int( 11) НЕ NULL, УНИКАЛЕН КЛЮЧ `uk_Times` (`TimeStr`));ВМЕСЕТЕ В `партидно тегло` (`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);
Запитване :
SET @bStartTime :='2017-09-29 11:10:00' SET @bEndTime :='2017-09-29 12:48:00'SELECT SrcTable, TimeStr, ValueFROM ( SELECT @row_num :=IF( @prev_value=u.SrcTable, @row_num + 1 ,1) AS RowNumber , u.* , @prev_value :=u.SrcTable FROM ( изберете 'ponumber' SrcTable , TimeStr, `Value` от ponumber union all select 'batch_number' SrcTable , TimeStr, `Value` от batch_number union all изберете 'batchweight' SrcTable , TimeStr, `Value` от batchweight ) u CROSS JOIN (SELECT @row_num :=1, @prev_value :='') BY SrcTORDable , TimeStr DESC ) dWHERE (d.TimeStr между @bStartTime и @bEndTime) ИЛИ (TimeStr <@bStartTime И RowNumber =1)
И така, това, което прави, е да се изчисли "RowNumber", който започва от 1 за най-новия ред за всяка таблица източник. След това тази извлечена таблица се филтрира или по времевия диапазон, или по номера на реда, ако не е в рамките на времевия диапазон.
Също така имайте предвид, че НЕ съм използвал СЪЮЗ
но вместо това са използвали UNION ALL
. Има голяма разлика в производителността и трябва да се научите да използвате всеки според нуждите. Ако използвате UNION
не използвайте също изберете различен
защото просто губите усилия.