मैं एक पोस्टग्रैज टेबल (जिसे "जीवन" कहा जाता है) के साथ काम कर रहा हूं, जिसमें time_stamp, usr_id, transaction_id, और life_remaining के कॉलम शामिल हैं। मुझे एक क्वेरी की आवश्यकता है जो मुझे प्रत्येक usr_id के लिए सबसे हालिया जीवन_प्रमाण प्रदान करेगी
- कई उपयोगकर्ता हैं (अलग usr_id के)
- टाइम_स्टैम्प एक विशिष्ट पहचानकर्ता नहीं है: कभी-कभी उपयोगकर्ता घटनाएँ (तालिका में पंक्ति द्वारा) एक ही टाइम_स्टैम्प के साथ घटित होंगी।
- trans_id केवल बहुत छोटी समय सीमाओं के लिए अद्वितीय है: समय के साथ यह दोहराता है
- शेष_लाइव (किसी दिए गए उपयोगकर्ता के लिए) समय के साथ बढ़ और घट सकता है
उदाहरण:
TIME_STAMP | lives_remaining | usr_id | trans_id ----------------------------------------- 07:00 | 1 | 1 | 1 09:00 | 4 | 2 | 2 10:00 | 2 | 3 | 3 10:00 | 1 | 2 | 4 11:00 | 4 | 1 | 5 11:00 | 3 | 1 | 6 13:00 | 3 | 3 | 1
जैसा कि मुझे प्रत्येक दिए गए usr_id के लिए नवीनतम डेटा के साथ पंक्ति के अन्य स्तंभों तक पहुंचने की आवश्यकता होगी, मुझे एक क्वेरी की आवश्यकता है जो इसके लिए एक परिणाम प्रदान करती है:
TIME_STAMP | lives_remaining | usr_id | trans_id ----------------------------------------- 11:00 | 3 | 1 | 6 10:00 | 1 | 2 | 4 13:00 | 3 | 3 | 1
जैसा कि उल्लेख किया गया है, प्रत्येक usr_id जीवन प्राप्त कर सकता है या खो सकता है, और कभी-कभी ये टाइमस्टैम्पेड घटनाएं एक साथ इतने करीब होती हैं कि उनके समान टाइमस्टैम्प होता है! इसलिए यह क्वेरी काम नहीं करेगी:
SELECT b.time_stamp,b.lives_remaining,b.usr_id,b.trans_id FROM
(SELECT usr_id, max(time_stamp) AS max_timestamp
FROM lives GROUP BY usr_id ORDER BY usr_id) a
JOIN lives b ON a.max_timestamp = b.time_stamp
इसके बजाय, मुझे सही पंक्ति की पहचान करने के लिए time_stamp (पहला) और trans_id (दूसरा) दोनों का उपयोग करना होगा। फिर मुझे उस जानकारी को उपकुंजियों से मुख्य क्वेरी तक पारित करने की आवश्यकता है जो उचित पंक्तियों के अन्य स्तंभों के लिए डेटा प्रदान करेगी। यह हैक की गई क्वेरी है जो मुझे काम करने के लिए मिली है:
SELECT b.time_stamp,b.lives_remaining,b.usr_id,b.trans_id FROM
(SELECT usr_id, max(time_stamp || '*' || trans_id)
AS max_timestamp_transid
FROM lives GROUP BY usr_id ORDER BY usr_id) a
JOIN lives b ON a.max_timestamp_transid = b.time_stamp || '*' || b.trans_id
ORDER BY b.usr_id
ठीक है, तो यह काम करता है, लेकिन मुझे यह पसंद नहीं है। इसके लिए एक क्वेरी के भीतर एक क्वेरी, एक सेल्फ जॉइन की आवश्यकता होती है, और मुझे लगता है कि यह उस पंक्ति को हथियाने से बहुत सरल हो सकता है जिसे MAX ने सबसे बड़ा टाइमस्टैम्प और ट्रांस_ड पाया। तालिका "जीवन" में पार्स करने के लिए लाखों पंक्तियाँ हैं, इसलिए मैं चाहूंगा कि यह क्वेरी यथासंभव तेज़ और कुशल हो। मैं विशेष रूप से RDBM और Postgres में नया हूं, इसलिए मुझे पता है कि मुझे उचित अनुक्रमित का प्रभावी उपयोग करने की आवश्यकता है। मैं अनुकूलित करने के तरीके पर थोड़ा खो गया हूं।
मुझे यहां इसी तरह की चर्चा मिली । क्या मैं ओरेकल एनालिटिकल फंक्शन के समकक्ष कुछ प्रकार के पोस्टग्रेज कर सकता हूं?
एक समग्र कार्य (जैसे MAX) द्वारा उपयोग किए जाने वाले संबंधित कॉलम की जानकारी तक पहुँचने पर कोई सलाह, इंडेक्स बनाने और बेहतर प्रश्न बनाने के लिए बहुत सराहना की जाएगी!
PS आप मेरे उदाहरण के मामले को बनाने के लिए निम्नलिखित का उपयोग कर सकते हैं:
create TABLE lives (time_stamp timestamp, lives_remaining integer,
usr_id integer, trans_id integer);
insert into lives values ('2000-01-01 07:00', 1, 1, 1);
insert into lives values ('2000-01-01 09:00', 4, 2, 2);
insert into lives values ('2000-01-01 10:00', 2, 3, 3);
insert into lives values ('2000-01-01 10:00', 1, 2, 4);
insert into lives values ('2000-01-01 11:00', 4, 1, 5);
insert into lives values ('2000-01-01 11:00', 3, 1, 6);
insert into lives values ('2000-01-01 13:00', 3, 3, 1);