मैं प्रत्येक उपयोगकर्ता के लिए नवीनतम रिकॉर्ड तिथि के लिए sql क्वेरी कैसे कर सकता हूं


228

मेरे पास एक तालिका है जो एक संग्रह प्रविष्टियों के रूप में है जब एक उपयोगकर्ता को लॉग ऑन किया गया था।

username, date,      value
--------------------------
brad,     1/2/2010,  1.1
fred,     1/3/2010,  1.0
bob,      8/4/2009,  1.5
brad,     2/2/2010,  1.2
fred,     12/2/2009, 1.3

etc..

मैं एक क्वेरी कैसे बनाऊं जो मुझे प्रत्येक उपयोगकर्ता के लिए नवीनतम तारीख दे?

अद्यतन: मैं यह भूल गया कि मुझे नवीनतम दिनांक के साथ एक मान होना चाहिए।


7
आप किस डेटाबेस का उपयोग कर रहे हैं? MySQL, SQL- सर्वर, Oracle, ...?
पीटर लैंग

1
क्या आपको उस मूल्य की आवश्यकता है जो नवीनतम तिथि, या अधिकतम मूल्य और अधिकतम तिथि के साथ जाती है?
मैथ्यू जोन्स

जवाबों:


381
select t.username, t.date, t.value
from MyTable t
inner join (
    select username, max(date) as MaxDate
    from MyTable
    group by username
) tm on t.username = tm.username and t.date = tm.MaxDate

3
जब postgresql के साथ काम कर रहा है, तो क्या यह संस्करण इनर जॉइन के बजाय IN (सबक्वेरी) का उपयोग करने से तेज होगा?
एक

3
@ मेरे अनुभव के रूप में, आंतरिक जुड़ाव का उपयोग करने की स्थिति में तेज है
दादा

14
इस दृष्टिकोण के साथ सावधान: यह प्रति उपयोगकर्ता एक से अधिक पंक्ति लौटा सकता है यदि उनके पास प्रति दिनांक एक से अधिक रिकॉर्ड है ( max(date)एक तारीख लौटाएगा जो कई रिकॉर्डों में शामिल हो जाएगा)। इस समस्या से बचने के लिए, @ dotjoe के समाधान का उपयोग करना बेहतर होगा: stackoverflow.com/a/2411763/4406793
मार्को रॉय

@RedFilter इसने मेरी समस्या के लिए एकदम सही काम किया। ऐसी तकनीकी क्वेरी के लिए बहुत बहुत धन्यवाद। वैसे मैंने किसी विशेष तिथि के लिए कई परिणाम प्राप्त करने से बचने के लिए डेट के बजाय डेटाइम का उपयोग किया
मुहम्मद खान

आपको 't.date = tm.MaxDate' की आवश्यकता क्यों नहीं होगी?
दुलड़ी

125

विंडो फ़ंक्शंस का उपयोग करना (Oracle में काम करता है, Postgres 8.4, SQL Server 2005, DB2, Sybase, Firebird 3.0, MariaDB 3.3)

select * from (
    select
        username,
        date,
        value,
        row_number() over(partition by username order by date desc) as rn
    from
        yourtable
) t
where t.rn = 1

1
वर्थ स्पष्ट करना कि कौन सा Sybase उत्पाद / संस्करण है। यह Sybase एएसई पर काम नहीं करता 16.
विचित्र levant

2
इस दृष्टिकोण का एक बड़ा लाभ यह है कि इसे प्रति विभाजन केवल एक पंक्ति में वापस करने की गारंटी है ( usernameइस मामले में) और यहां तक ​​कि एक अद्वितीय "ऑर्डर करने योग्य" फ़ील्ड की आवश्यकता नहीं है (जैसे max(date)अन्य उत्तरों में शामिल होना )।
मार्को रॉय

1
बस कुछ जोड़ने के लिए @MarcoRoy ने कहा, यदि आप एक ही अधिकतम तिथि के साथ एक से अधिक रिकॉर्ड रखते हैं, यदि आप क्वेरी बदलते हैं, जैसे जब आप इसे डीबग कर रहे हैं, तो एक अलग रिकॉर्ड 1 की पंक्ति संख्या प्राप्त कर सकता है, इसलिए परिणाम असंगत हो सकते हैं। लेकिन जब तक आप वास्तव में परवाह नहीं करते हैं, तब तक यह समस्या नहीं होनी चाहिए। यदि आप तारीख के बाद पीके जोड़ते हैं तो इसे हल किया जा सकता है। उदाहरण के लिए order by date desc, id desc):।
एंड्रयू

40

मुझे लगता है कि अधिकांश डेवलपर्स भारी डेटा पर इसके प्रभाव पर विचार किए बिना एक इनलाइन क्वेरी का उपयोग करते हैं।

बस, आप इसे प्राप्त कर सकते हैं:

SELECT a.username, a.date, a.value
FROM myTable a
LEFT OUTER JOIN myTable b
ON a.username = b.username 
AND a.date < b.date
WHERE b.username IS NULL
ORDER BY a.date desc;

3
वास्तव में यह केवल डुप्लिकेट के लिए काम करता है, यदि आपके पास 2 से अधिक मान हैं, तो स्थिति a.date <b.date काम नहीं करती है, इसका अर्थ है, यह एक सामान्य समाधान नहीं है, हालांकि LEFT OUTER JOIN के साथ काम करने का विचार महत्वपूर्ण है इस जवाब में बात।
iversoncru

दिलचस्प बात यह छोटे (के लिए Sybase एएसई 16 काम करता है ठीक <(100k पंक्ति) यह hungs ... मैंने सोचा था कि इस आदर्श उदाहरण संबंधपरक डीबीएस ... पर उत्कृष्टता प्राप्त करना चाहिए होगा 10k पंक्ति) टेबल, लेकिन बड़े लोगों के साथ>
levant विचित्र

1
@ एलिवेंटेड ... हाँ लेफ्ट जॉइन बड़े डेटासेट पर महंगा है। यदि संभव हो तो इसे किसी तरह से संभालने के लिए आप स्वयं पर फ़िल्टर स्थिति डालकर एक प्रदर्शन को मोड़ सकते हैं।
सुजीत

21

उपयोगकर्ता के लिए अधिकतम तिथि वाली संपूर्ण पंक्ति प्राप्त करने के लिए:

select username, date, value
from tablename where (username, date) in (
    select username, max(date) as date
    from tablename
    group by username
)


1
सावधान रहें कि यह आपको डुप्लिकेट देगा यदि किसी विशिष्ट उपयोगकर्ता के लिए एक ही तारीख के साथ एक से अधिक रिकॉर्ड है। आप यह चाहते हैं या नहीं कर सकते हैं।
एंड्रयू

यह एसक्यूएल में ओरेकल के साथ धीमी गति से धीमी है, यह सूचकांक का उपयोग नहीं करेगा
मीडिलई

9
SELECT *     
FROM MyTable T1    
WHERE date = (
   SELECT max(date)
   FROM MyTable T2
   WHERE T1.username=T2.username
)

4
जबकि यह एक और संभव समाधान है, यह आमतौर पर इसे हल करने का एक अच्छा तरीका नहीं है। इस तरह से करने से तालिका में प्रत्येक नाम के लिए एक बार चलने के लिए आंतरिक क्वेरी का कारण होगा, जिससे महत्वपूर्ण आकार की किसी भी तालिका के लिए एक बड़ी मंदी होगी। एक अलग क्वेरी करना जिसमें पहली क्वेरी से एक तत्व नहीं है जहां क्लॉज तब दो तालिकाओं में शामिल होने से आमतौर पर तेजी से होगा।
स्कॉट चैंबरलेन

यह अधिक समझ में आने वाले समाधानों में से एक होने की अच्छी विशेषता है जो कि विशिष्ट कार्यान्वयन नहीं है।
माइकल स्ज़ेपेपनिएक

7

मेरे अनुभव से सबसे तेज़ तरीका प्रत्येक पंक्ति लेना है जिसके लिए तालिका में कोई नई पंक्ति नहीं है।

एक अन्य लाभ यह है कि प्रयुक्त वाक्यविन्यास बहुत सरल है, और यह कि क्वेरी का अर्थ समझ में आसान है (सभी पंक्तियों को ऐसे लें कि उपयोगकर्ता नाम के लिए कोई नई पंक्ति मौजूद नहीं है)।

मौजूद नहीं

SELECT username, value
FROM t
WHERE NOT EXISTS (
  SELECT *
  FROM t AS witness
  WHERE witness.username = t.username AND witness.date > t.date
);

पंक्ति संख्या

SELECT username, value
FROM (
  SELECT username, value, row_number() OVER (PARTITION BY username ORDER BY date DESC) AS rn
  FROM t
) t2
WHERE rn = 1

आंतरिक रूप से जुड़ा

SELECT t.username, t.value
FROM t
INNER JOIN (
  SELECT username, MAX(date) AS date
  FROM t
  GROUP BY username
) tm ON t.username = tm.username AND t.date = tm.date;

बाईं ओर का बाहरी जोड़

SELECT username, value
FROM t
LEFT OUTER JOIN t AS w ON t.username = w.username AND t.date < w.date
WHERE w.username IS NULL

मुझे कठिनाई नहीं समझ में आ रहा है संस्करण। क्या आप सबक्वेरी भाग में एकत्रीकरण नहीं कर रहे हैं? यदि मैं इसे अपनी मेज पर चलाता हूं तो मुझे केवल 40 कर्मचारियों के 3 कर्मचारी रिकॉर्ड वापस मिल जाते हैं जो मेरे पास तालिका में हैं। मुझे कम से कम 40 रिकॉर्ड मिलने चाहिए। आंतरिक प्रश्न में, क्या हमें उपयोगकर्ता नाम से भी मेल नहीं खाना चाहिए?
नर्षे

यह मेरे लिए निम्नलिखित का उपयोग करके काम करता है:SELECT username, value FROM t WHERE NOT EXISTS ( SELECT * FROM t AS witness WHERE witness.date > t.date AND witness.username = t.username );
नरेश

मैंने NOT EXISTS को देखा है और यह केवल विरोध के रूप में सभी उपयोगकर्ताओं के लिए उच्च प्रविष्टि को वापस करने के लिए दिखता है: "एक क्वेरी जो मुझे प्रत्येक उपयोगकर्ता के लिए नवीनतम तारीख देगी"।
तसोस ज़र्वोस

आप वास्तव में सही हैं, मैं अपनी क्वेरी को अपडेट करता हूं। आपकी टिप्पणी के लिए धन्यवाद! @ नरेश क्षमा करें, मैंने किसी कारणवश आपकी टिप्पणियों को याद किया: / लेकिन आप बिल्कुल सही हैं।
फाबियान पीजेके

2

यह आपको आपके संपादित प्रश्न का सही परिणाम देना चाहिए।

उप-क्वेरी नवीनतम तिथि की केवल पंक्तियों को खोजना सुनिश्चित करती है, और बाहरी GROUP BYसंबंधों का ध्यान रखेगी। जब एक ही उपयोगकर्ता के लिए एक ही तिथि के लिए दो प्रविष्टियाँ होती हैं, तो यह उच्चतम के साथ एक लौटेगा value

SELECT t.username, t.date, MAX( t.value ) value
FROM your_table t
JOIN (
       SELECT username, MAX( date ) date
       FROM your_table
       GROUP BY username
) x ON ( x.username = t.username AND x.date = t.date )
GROUP BY t.username, t.date

1

आप विश्लेषणात्मक रैंक फ़ंक्शन का उपयोग भी कर सकते हैं

    with temp as 
(
select username, date, RANK() over (partition by username order by date desc) as rnk from t
)
select username, rnk from t where rnk = 1

0
SELECT Username, date, value
 from MyTable mt
 inner join (select username, max(date) date
              from MyTable
              group by username) sub
  on sub.username = mt.username
   and sub.date = mt.date

अद्यतन समस्या का समाधान करेगा। यह बड़ी तालिकाओं पर इतनी अच्छी तरह से काम नहीं कर सकता है, यहां तक ​​कि अच्छी अनुक्रमण के साथ भी।


0
SELECT *
FROM ReportStatus c
inner join ( SELECT 
  MAX(Date) AS MaxDate
  FROM ReportStatus ) m
on  c.date = m.maxdate

0

ओरेकल के लिए अवरोही क्रम में सेट किया गया परिणाम और पहला रिकॉर्ड लेता है, इसलिए आपको नवीनतम रिकॉर्ड मिलेगा:

select * from mytable
where rownum = 1
order by date desc

0
SELECT DISTINCT Username, Dates,value 
FROM TableName
WHERE  Dates IN (SELECT  MAX(Dates) FROM TableName GROUP BY Username)


Username    Dates       value
bob         2010-02-02  1.2       
brad        2010-01-02  1.1       
fred        2010-01-03  1.0       

यह संभवत: तब काम नहीं करेगा जब एक ही तिथि पर कई उपयोगकर्ताओं के पास ऑर्डर हों; क्या होगा अगर ब्रैड और बॉब दोनों का 2 जनवरी को आदेश था?
ऐहगिन्स

मैं उपयोगकर्ता नाम से समूहीकरण कर रहा हूं, इसलिए यह काम करेगा और परिणाम इस प्रकार होंगे: उपयोगकर्ता नाम दिनांक मान २०१०-०२-०२-२०२० २०१०-०२-०२-२०१२ १.२ फ्रेड २०१०-०१-०३ १.०
वार

0
SELECT t1.username, t1.date, value
FROM MyTable as t1
INNER JOIN (SELECT username, MAX(date)
            FROM MyTable
            GROUP BY username) as t2 ON  t2.username = t1.username AND t2.date = t1.date

4
कार्यान्वयन या स्पष्टीकरण पर एक वाक्य या दो गुणवत्ता जवाब बनाने की दिशा में एक लंबा रास्ता तय करता है।

0

Select * from table1 where lastest_date=(select Max(latest_date) from table1 where user=yourUserName)

इनर क्वेरी वर्तमान उपयोगकर्ता के लिए नवीनतम तारीख वापस कर देगी, बाहरी क्वेरी आंतरिक क्वेरी परिणाम के अनुसार सभी डेटा को खींच लेगी।


0

मैंने प्रत्येक उपयोगकर्ता के लिए अंतिम रिकॉर्ड लेने के लिए इस तरह का उपयोग किया जो मेरे पास मेरी मेज पर है। यह पीडीए उपकरणों पर हाल के समय के अनुसार सेल्समैन के लिए अंतिम स्थान प्राप्त करने के लिए एक क्वेरी थी।

CREATE FUNCTION dbo.UsersLocation()
RETURNS TABLE
AS
RETURN
Select GS.UserID, MAX(GS.UTCDateTime) 'LastDate'
From USERGPS GS
where year(GS.UTCDateTime) = YEAR(GETDATE()) 
Group By GS.UserID
GO
select  gs.UserID, sl.LastDate, gs.Latitude , gs.Longitude
        from USERGPS gs
        inner join USER s on gs.SalesManNo = s.SalesmanNo 
        inner join dbo.UsersLocation() sl on gs.UserID= sl.UserID and gs.UTCDateTime = sl.LastDate 
        order by LastDate desc

0
SELECT * FROM TABEL1 WHERE DATE= (SELECT MAX(CREATED_DATE) FROM TABEL1)

StackOverflow में आपका स्वागत है और मदद करने के प्रयास के लिए धन्यवाद। समाधान की व्याख्या करने वाले उत्तरों की तुलना में आपके जैसे कोड-ही उत्तर कम सराहे जाते हैं।
यून्नोस्क

गुणवत्ता उत्तर प्रदान करने के लिए कृपया यह कैसे पढ़ें - उत्तर दें।
द वेवेयेरे

तथा। यह प्रत्येक उपयोगकर्ता नाम के लिए अधिकतम, केवल नवीनतम एकल पंक्ति में वापस नहीं आता है।
इरविनकैगु

0

मेरा छोटा संकलन

  • joinनेस्टेड से बेहतर स्वselect
  • लेकिन group byआप के primary keyलिए बेहतर है जो आपको नहीं देता हैjoin
  • यह कुंजी ( डॉक्स ) partition byके साथ मिलकर दी जा सकती हैfirst_value

तो, यहाँ एक प्रश्न है:

चुनते हैं
 टी। *
से 
 टेबल टी इनर जॉइन (
  ID के रूप में पहले first_value (ID) ओवर (GroupColumn ऑर्डर द्वारा विभाजन) ID के रूप में चुनें
  तालिका से
  जहां FilterColumn = 'value'
 ) j. t.ID = j.ID पर

पेशेवरों:

  • whereकिसी भी कॉलम का उपयोग करके विवरण के साथ डेटा को फ़िल्टर करें
  • select फ़िल्टर्ड पंक्तियों में से कोई भी कॉलम

विपक्ष:

  • MS SQL सर्वर को 2012 से शुरू करने की आवश्यकता है।

0

मैंने अपने आवेदन के लिए कुछ हद तक किया:

नीचे क्वेरी है:

select distinct i.userId,i.statusCheck, l.userName from internetstatus 
as i inner join login as l on i.userID=l.userID 
where nowtime in((select max(nowtime) from InternetStatus group by userID));    

0

यह ऊपर दिए गए उत्तरों में से एक के समान है, लेकिन मेरी राय में यह बहुत सरल और स्पष्ट है। इसके अलावा, क्रॉस लागू बयान के लिए एक अच्छा उपयोग दिखाता है। SQL सर्वर 2005 और इसके बाद के संस्करण के लिए ...

select
    a.username,
    a.date,
    a.value,
from yourtable a
cross apply (select max(date) 'maxdate' from yourtable a1 where a.username=a1.username) b
where a.date=b.maxdate

0
SELECT MAX(DATE) AS dates 
FROM assignment  
JOIN paper_submission_detail ON  assignment.PAPER_SUB_ID = 
     paper_submission_detail.PAPER_SUB_ID 

1
हालांकि यह कोड प्रश्न को हल कर सकता है, जिसमें यह भी बताया गया है कि यह समस्या कैसे और क्यों हल करती है, इससे वास्तव में आपके पोस्ट की गुणवत्ता को बेहतर बनाने में मदद मिलेगी, और संभवतः अधिक वोटों का परिणाम होगा। याद रखें कि आप भविष्य में पाठकों के लिए प्रश्न का उत्तर दे रहे हैं, न कि केवल उस व्यक्ति से जो अब पूछ रहा है। कृपया स्पष्टीकरण जोड़ने के लिए अपने उत्तर को संपादित करें और संकेत दें कि क्या सीमाएँ और मान्यताएँ लागू होती हैं। समीक्षा से
डबल-बीप

-2

उपयोगकर्ताओं के लिए सभी नवीनतम प्रविष्टियाँ प्राप्त करने के लिए भी यह काम करना चाहिए।

SELECT username, MAX(date) as Date, value
FROM MyTable
GROUP BY username, value

1
नमस्ते, मान स्तंभ को समूह द्वारा समूह में होना चाहिए।
जुआन रुइज़ डी कैस्टिला

-4

आप कुल फ़ंक्शन MAX और GROUP BY का उपयोग करेंगे

SELECT username, MAX(date), value FROM tablename GROUP BY username, value

7
आपका संपादन केवल एक यादृच्छिक ही उठाएगा value, न कि MAX(date)पंक्ति से जुड़ा हुआ ।
एलिसन आर।

यह अधिकतम तारीख देगा लेकिन उपयोगकर्ता नाम और मूल्य एक ही रिकॉर्ड के नहीं हो सकते हैं।
SKR
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.