2009-07-16 10 views
60

मैं आईपी, उपयोगकर्ता और सबसे हालिया टाइमस्टैम्प प्राप्त करने की कोशिश कर रहा हूं जिसमें एक उपयोगकर्ता के लिए वर्तमान आईपी और एक या अधिक पहले हो सकता है ips। मुझे सबसे हालिया आईपी और संबंधित टाइमस्टैम्प युक्त प्रत्येक उपयोगकर्ता के लिए एक पंक्ति चाहिए। एक टेबल इस तरह दिखता है यदि ऐसा है तो:किसी दिए गए कुंजी के प्रत्येक उदाहरण के लिए सबसे हालिया पंक्ति प्राप्त करने के लिए एसक्यूएल क्वेरी

username  | ip  | time_stamp 
--------------|----------|-------------- 
ted   | 1.2.3.4 | 10 
jerry   | 5.6.6.7 | 12 
ted   | 8.8.8.8 | 30 

मैं क्वेरी के उत्पादन में उम्मीद थी होने के लिए:

jerry | 5.6.6.7 | 12 
ted  | 8.8.8.8 | 30 

मैं एक एकल एसक्यूएल क्वेरी में यह कर सकते हैं? यदि यह महत्वपूर्ण है, तो डीबीएमएस पोस्टग्रेस्क्ल है।

उत्तर

90

इस प्रयास करें:

Select u.[username] 
     ,u.[ip] 
     ,q.[time_stamp] 
From [users] As u 
Inner Join (
    Select [username] 
      ,max(time_stamp) as [time_stamp] 
    From [users] 
    Group By [username]) As [q] 
On u.username = q.username 
And u.time_stamp = q.time_stamp 
+0

मैं सही रास्ते पर था लेकिन मुझे सही शामिल नहीं हो सका। यह चाल है। धन्यवाद! – alanc10n

+2

क्या यह SQL सर्वर में काम करता है? समान डेटा पर एक ही चीज़ की कोशिश की लेकिन मुझे केवल "आईपी" के लिए एक पंक्ति मिल रही है, जिसमें सबसे हालिया टाइमस्टैम्प भी है। – tcash21

+0

एक हाना तालिका के खिलाफ प्रयुक्त, इसने कई पंक्तियों का उत्पादन किया जहां 1 की उम्मीद थी। हाना में ऐसी कई चीजें हैं जो लोकप्रिय एसक्यूएल इंजनों के समान नहीं हैं। –

7

कुछ इस तरह:

select * 
from User U1 
where time_stamp = (
    select max(time_stamp) 
    from User 
    where username = U1.username) 

यह करना चाहिए।

+0

यह काम करेगा यदि 'time_stamp' अद्वितीय होगा और आप इसे ग्रहण नहीं कर सकते हैं। – Nux

3

उपरोक्त दोनों उत्तरों का मानना ​​है कि आपके पास प्रत्येक उपयोगकर्ता और टाइम_स्टैम्प के लिए केवल एक पंक्ति है। आवेदन और आपके टाइम_स्टैम्प की ग्रैन्युलरिटी के आधार पर यह मान्य मान्यता नहीं हो सकती है। यदि आपको किसी दिए गए उपयोगकर्ता के लिए time_stamp के संबंधों से निपटने की आवश्यकता है, तो आपको ऊपर दिए गए उत्तरों में से एक को विस्तारित करना होगा।

इसे एक प्रश्न में लिखने के लिए एक और नेस्टेड उप-क्वेरी की आवश्यकता होगी - चीजें अधिक गन्दा हो रही हैं और प्रदर्शन का सामना करना पड़ेगा।

मुझे यह टिप्पणी के रूप में जोड़ना अच्छा लगेगा, लेकिन मेरे पास अभी तक 50 प्रतिष्ठा नहीं है क्योंकि एक नया जवाब पोस्ट करने के लिए खेद है!

+5

"उपर्युक्त दोनों ..." एक उत्तर शुरू करने का एक अच्छा तरीका नहीं है। मुझे कैसे पता चलेगा कि क्या ऊपर दिए गए उत्तरों आप जिनके बारे में बात कर रहे हैं? उत्तर उनके स्कोर के आधार पर एक अलग क्रम में प्रकट हो सकते हैं। –

+6

रॉब, मुझे नहीं लगता कि आप उसे कुछ बता रहे हैं जिसे वह नहीं जानता है।वह टिप्पणी नहीं कर सकता है और जिन उत्तरों का जिक्र कर रहा था वे स्पष्ट रूप से त्रुटिपूर्ण थे। क्या महत्वपूर्ण है, ज्ञान फैलाना या पाठ कहां रखा गया था? – cruskai239

0

मैं इसका उपयोग कर रहा हूं क्योंकि मैं किसी अन्य तालिका से परिणाम लौटा रहा हूं। हालांकि मैं नेस्टेड जॉइन से बचने की कोशिश कर रहा हूं अगर यह w/एक कम कदम में मदद करता है। ओह अच्छा। यह वही बात देता है।

select 
users.userid 
, lastIP.IP 
, lastIP.maxdate 

from users 

inner join (
    select userid, IP, datetime 
    from IPAddresses 
    inner join (
     select userid, max(datetime) as maxdate 
     from IPAddresses 
     group by userid 
     ) maxIP on IPAddresses.datetime = maxIP.maxdate and IPAddresses.userid = maxIP.userid 
    ) as lastIP on users.userid = lastIP.userid 
+0

मुझे लगता है कि यह उपर्युक्त उपयोगकर्ता की प्रतिक्रिया – jawz101

29

ROW_NUMBER खिड़की समारोह के साथ अच्छा सुरुचिपूर्ण समाधान (PostgreSQL द्वारा समर्थित - SQL Fiddle में देखें):

SELECT username, ip, time_stamp FROM (
SELECT username, ip, time_stamp, 
    ROW_NUMBER() OVER (PARTITION BY username ORDER BY time_stamp DESC) rn 
FROM Users 
) tmp WHERE rn = 1; 
+2

का उत्तर है यह सबसे अच्छा जवाब है, क्योंकि इसमें नेस्टेड क्वेरी में शामिल होने शामिल नहीं है। केवल समस्या यह है कि इसे [आईपी] कुंजी में और प्रश्न के अनुसार उपयोगकर्ता नाम शामिल करने की आवश्यकता है। – dashnick

1

अभी तक टिप्पणी पोस्ट नहीं कर सकते, लेकिन @Cristi एस का जवाब मेरे लिए एक इलाज काम करता है ।

मेरे परिदृश्य में, मुझे सभी product_ids के लिए Lowest_Offers में केवल नवीनतम 3 रिकॉर्ड रखने की आवश्यकता है।

हटाने के लिए अपने एसक्यूएल को फिर से काम करने की आवश्यकता है - सोचा कि यह ठीक रहेगा, लेकिन वाक्यविन्यास गलत है।

DELETE from (
SELECT product_id, id, date_checked, 
    ROW_NUMBER() OVER (PARTITION BY product_id ORDER BY date_checked DESC) rn 
FROM lowest_offers 
) tmp WHERE > 3; 
+0

सही एसक्यूएल: Lowest_Offer से हटाएँ \t \t कहां ( \t चुनें (date_checked DESC द्वारा product_id आदेश) द्वारा PARTITION से अधिक \t से आईडी ( \t \t चयन product_id, आईडी, date_checked, \t \t ROW_NUMBER() में आईडी आर.एन. Lowest_Offer से \t) tmp कहां आरएन> 3 ) – err1

संबंधित मुद्दे

 संबंधित मुद्दे