मान लीजिए आप एक विस्तारित विनिमय दर तालिका कि निहित था:।
Start Date End Date Rate
========== ========== =======
0001-01-01 2009-01-31 40.1
2009-02-01 2009-02-28 40.1
2009-03-01 2009-03-31 41.0
2009-04-01 2009-04-30 38.5
2009-05-01 9999-12-31 42.7
हम कर सकते हैं इस बारे में चर्चा करें कि पहले दो पंक्तियों को संयुक्त किया जाना चाहिए, लेकिन सामान्य विचार यह है कि किसी दिए गए दिनांक के लिए विनिमय दर को खोजना मुश्किल है। यह संरचना SQL 'BETWEEN' ऑपरेटर के साथ काम करती है जिसमें श्रेणियों के सिरों को शामिल किया गया है। अक्सर, श्रेणियों के लिए एक बेहतर प्रारूप 'खुला-बंद' होता है; सूचीबद्ध पहली तारीख शामिल है और दूसरा शामिल है। ध्यान दें कि डेटा पंक्तियों पर एक बाधा है - (ए) तिथियों की सीमा के कवरेज में कोई अंतराल नहीं है और (बी) कवरेज में कोई ओवरलैप नहीं है। उन बाधाओं को लागू करना पूरी तरह से तुच्छ नहीं है (विनम्र अल्पसंख्यक - मीओसिस)।
अब बुनियादी क्वेरी तुच्छ है, और मामले बी नहीं रह गया है एक विशेष मामला है:
SELECT T.Date, T.Amount, X.Rate
FROM Transactions AS T JOIN ExtendedExchangeRates AS X
ON T.Date BETWEEN X.StartDate AND X.EndDate;
मुश्किल हिस्सा मक्खी पर दिए गए ExchangeRate मेज से ExtendedExchangeRate तालिका पैदा कर रही है। यदि यह एक विकल्प है, तो विस्तारित एक्सचेंजरेट तालिका से मेल खाने के लिए मूल एक्सचेंजरेट तालिका की संरचना को संशोधित करना एक अच्छा विचार होगा; जब आप किसी विनिमय दर को निर्धारित करने की आवश्यकता होती है (दिन में कई बार) की आवश्यकता होती है तो डेटा गड़बड़ी को हल करता है (महीने में एक बार)।
विस्तारित विनिमय दर तालिका कैसे बनाएं? यदि आपका सिस्टम अगले या पिछले दिन प्राप्त करने के लिए दिनांक मूल्य से 1 जोड़ने या घटाने का समर्थन करता है (और इसमें एक एकल पंक्ति तालिका 'डुअल' है), तो इस पर एक भिन्नता काम करेगी (किसी भी ओलाप फ़ंक्शन का उपयोग किए बिना):
CREATE TABLE ExchangeRate
(
Date DATE NOT NULL,
Rate DECIMAL(10,5) NOT NULL
);
INSERT INTO ExchangeRate VALUES('2009-02-01', 40.1);
INSERT INTO ExchangeRate VALUES('2009-03-01', 41.0);
INSERT INTO ExchangeRate VALUES('2009-04-01', 38.5);
INSERT INTO ExchangeRate VALUES('2009-05-01', 42.7);
प्रथम पंक्ति:
SELECT '0001-01-01' AS StartDate,
(SELECT MIN(Date) - 1 FROM ExchangeRate) AS EndDate,
(SELECT Rate FROM ExchangeRate
WHERE Date = (SELECT MIN(Date) FROM ExchangeRate)) AS Rate
FROM Dual;
परिणाम:
0001-01-01 2009-01-31 40.10000
अंतिम पंक्ति:
+०१२३५१६४१०
SELECT (SELECT MAX(Date) FROM ExchangeRate) AS StartDate,
'9999-12-31' AS EndDate,
(SELECT Rate FROM ExchangeRate
WHERE Date = (SELECT MAX(Date) FROM ExchangeRate)) AS Rate
FROM Dual;
परिणाम:
2009-05-01 9999-12-31 42.70000
मध्य पंक्तियों:
SELECT X1.Date AS StartDate,
X2.Date - 1 AS EndDate,
X1.Rate AS Rate
FROM ExchangeRate AS X1 JOIN ExchangeRate AS X2
ON X1.Date < X2.Date
WHERE NOT EXISTS
(SELECT *
FROM ExchangeRate AS X3
WHERE X3.Date > X1.Date AND X3.Date < X2.Date
);
परिणाम:
2009-02-01 2009-02-28 40.10000
2009-03-01 2009-03-31 41.00000
2009-04-01 2009-04-30 38.50000
ध्यान दें कि मौजूद नहीं उप क्वेरी बल्कि महत्वपूर्ण है। इसके बिना, 'मध्य पंक्तियों' परिणाम है:
2009-02-01 2009-02-28 40.10000
2009-02-01 2009-03-31 40.10000 # Unwanted
2009-02-01 2009-04-30 40.10000 # Unwanted
2009-03-01 2009-03-31 41.00000
2009-03-01 2009-04-30 41.00000 # Unwanted
2009-04-01 2009-04-30 38.50000
अवांछित पंक्तियों की संख्या के आकार में तालिका बढ़ने के साथ नाटकीय रूप से बढ़ (एन> 2 पंक्तियों के लिए, देखते हैं (एन 2) * (एन - 3)/2 अवांछित पंक्तियां, मुझे विश्वास है)।
SELECT DATE '0001-01-01' AS StartDate,
(SELECT MIN(Date) - 1 FROM ExchangeRate) AS EndDate,
(SELECT Rate FROM ExchangeRate
WHERE Date = (SELECT MIN(Date) FROM ExchangeRate)) AS Rate
FROM Dual
UNION
SELECT X1.Date AS StartDate,
X2.Date - 1 AS EndDate,
X1.Rate AS Rate
FROM ExchangeRate AS X1 JOIN ExchangeRate AS X2
ON X1.Date < X2.Date
WHERE NOT EXISTS
(SELECT *
FROM ExchangeRate AS X3
WHERE X3.Date > X1.Date AND X3.Date < X2.Date
)
UNION
SELECT (SELECT MAX(Date) FROM ExchangeRate) AS StartDate,
DATE '9999-12-31' AS EndDate,
(SELECT Rate FROM ExchangeRate
WHERE Date = (SELECT MAX(Date) FROM ExchangeRate)) AS Rate
FROM Dual;
परीक्षण डीबीएमएस पर (आईबीएम इन्फोर्मिक्स गतिशील सर्वर 11.50.FC6 MacOS एक्स 10.6.2 पर), मैं करने में सक्षम था:
ExtendedExchangeRate के लिए परिणाम (संबंध तोड़ना) तीन प्रश्नों का मिलन है एक दृश्य में जिज्ञासा को बदलने, लेकिन मैं डेटा प्रकार के साथ धोखा दे बंद करना पड़ा - दिनांकों में तार मजबूर द्वारा:
CREATE VIEW ExtendedExchangeRate(StartDate, EndDate, Rate) AS
SELECT DATE('0001-01-01') AS StartDate,
(SELECT MIN(Date) - 1 FROM ExchangeRate) AS EndDate,
(SELECT Rate FROM ExchangeRate WHERE Date = (SELECT MIN(Date) FROM ExchangeRate)) AS Rate
FROM Dual
UNION
SELECT X1.Date AS StartDate,
X2.Date - 1 AS EndDate,
X1.Rate AS Rate
FROM ExchangeRate AS X1 JOIN ExchangeRate AS X2
ON X1.Date < X2.Date
WHERE NOT EXISTS
(SELECT *
FROM ExchangeRate AS X3
WHERE X3.Date > X1.Date AND X3.Date < X2.Date
)
UNION
SELECT (SELECT MAX(Date) FROM ExchangeRate) AS StartDate,
DATE('9999-12-31') AS EndDate,
(SELECT Rate FROM ExchangeRate WHERE Date = (SELECT MAX(Date) FROM ExchangeRate)) AS Rate
FROM Dual;
क्या वे वास्तव में आपके पास टेबल हैं, या आपने सरल बना दिया है? क्या आप अधिक जानकारी प्रदान कर सकते हैं? क्या आपके पास अन्य पहचानकर्ता, पीके आदि हैं? – van
बेशक वास्तविकता में कई और चल रहे हैं (एकाधिक मुद्राएं, आदि) लेकिन यह अनिवार्य रूप से इसे प्राप्त करना चाहता था। –
बस जानकारी के लिए ... कृपया ध्यान दें कि मेरा समाधान मूल रूप से विभिन्न मुद्राओं के लिए भी काम करता है, लेकिन आपको 'इंडेक्सेड एक्सचेंजरेट' में पंक्ति संख्या को प्रति मुद्रा ('भाग' का उपयोग करके) में बदलना होगा और इसे 'LEFT' में जोड़ें 'RangedExchangeRate' में जॉइन की स्थिति। – Lucero