लंबे/जटिल प्रश्नों की तुलना में छोटे और सरल प्रश्नों पर अधिक ध्यान दिया जाता है। ऐसा इसलिए नहीं है क्योंकि हम उत्तर नहीं दे सकते, लेकिन इतने सारे प्रश्नों के साथ, और इतने कम स्वयंसेवक समय के साथ, बड़े प्रश्नों को पढ़ने के लिए समय को सही ठहराना कठिन है।
हालाँकि मुझे लगता है कि आपकी बुनियादी आवश्यकता उतनी जटिल नहीं है। आप एक समय सीमा के भीतर आने वाली पंक्तियों को पुनः प्राप्त करने का एक तरीका चाहते हैं या यदि उस सीमा में नहीं हैं तो उस सीमा की निकटतम पंक्तियाँ प्रदान करें।
ROW_NUMBER() OVER() का समर्थन करने वाले डेटाबेस में यह काफी आसान है (और MySQL 8.x को इसका समर्थन करने की योजना है), लेकिन उस समय तक row_number() का अनुकरण करने के लिए आप चर और एक आदेशित सबक्वेरी का उपयोग कर सकते हैं।
आप इस समाधान का परीक्षण यहां SQL Fiddle पर कर सकते हैं।
MySQL 5.6 स्कीमा सेटअप :
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);
क्वेरी :
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)
तो, यह क्या करता है "पंक्ति संख्या" की गणना करता है जो प्रत्येक स्रोत तालिका के लिए सबसे हालिया पंक्ति के लिए 1 से शुरू होता है। फिर इस व्युत्पन्न तालिका को या तो समय सीमा के अनुसार फ़िल्टर किया जाता है, या पंक्ति संख्या द्वारा यदि समय सीमा के भीतर नहीं तो फ़िल्टर किया जाता है।
यह भी ध्यान दें कि मैंने उपयोग नहीं किया UNION
लेकिन इसके बजाय UNION ALL
. का उपयोग किया है . प्रदर्शन में बहुत बड़ा अंतर है और प्रत्येक को आवश्यकता के अनुसार उपयोग करना सीखना चाहिए। यदि UNION
का उपयोग कर रहे हैं select distinct
. का भी उपयोग न करें क्योंकि आप सिर्फ मेहनत बर्बाद कर रहे हैं।
परिणाम :
| 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 |