আমি প্রতিটি ব্যবহারকারীর জন্য সর্বশেষ রেকর্ড তারিখের জন্য কীভাবে এসকিএল জিজ্ঞাসা করব


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
আপনি কোন ডাটাবেস ব্যবহার করছেন? মাইএসকিউএল, এসকিউএল-সার্ভার, ওরাকল, ...?
পিটার ল্যাং

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
পোস্টগ্র্যাস্কল নিয়ে কাজ করার সময় এই সংস্করণটি অভ্যন্তরীণ যোগদানের পরিবর্তে কোনও আইএন (সাবকোয়ারি) ব্যবহারের চেয়ে দ্রুত হবে?
এক

3
@ আমার অভিজ্ঞতা হিসাবে একক, অভ্যন্তরীণ যোগদান ব্যবহার করা শর্তের চেয়ে দ্রুত
দাদা

13
এই পদ্ধতির সাথে যত্নবান: যদি তারা প্রতি তারিখে একাধিক রেকর্ড থাকে তবে এটি প্রতি একাধিক সারিতে max(date)ফিরতে পারে ( একাধিক রেকর্ডে যোগদানের তারিখটি ফিরিয়ে দেবে)। : এই সমস্যাটি এড়ানোর জন্য, এটি ব্যবহার করার জন্য @ dotjoe এর সমাধান বাঞ্ছনীয় হবে stackoverflow.com/a/2411763/4406793
মার্কো রায়

@ রেডফিল্টার এটি আমার সমস্যার জন্য নিখুঁতভাবে কাজ করেছে। এই জাতীয় প্রযুক্তিগত প্রশ্নের জন্য অনেক ধন্যবাদ। কোনও নির্দিষ্ট তারিখের জন্য একাধিক ফলাফল পেতে এড়াতে আমি তারিখের পরিবর্তে ডেটটাইম ব্যবহার করেছি
মুহাম্মদ খান

আপনার কেন 'এবং t.date = tm.MaxDate' দরকার নেই কেন গ্রুপিং যথেষ্ট হবে না?
দুলদি

125

উইন্ডো ফাংশনগুলি ব্যবহার করে (ওরাকল, পোস্টগ্রিস 8.4, এসকিউএল সার্ভার 2005, ডিবি 2, সিবাস, ফায়ারবার্ড 3.0, মারিয়াডিবি 10.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
কোন সাইবেসের পণ্য / সংস্করণ তা স্পষ্ট করে জানাচ্ছে। এটা তোলে সাইবেস ASE কাজ করে না 16.
Pied লেভান্ট

2
এই পদ্ধতির usernameএকটি বৃহত সুবিধা হ'ল পার্টিশন প্রতি সর্বদা কেবল একটি সারি ফেরত দেওয়ার গ্যারান্টিযুক্ত ( এই ক্ষেত্রে) এবং এমনকি কোনও অনন্য "অনুগামী" ক্ষেত্রের প্রয়োজন হয় না (যেমন max(date)অন্যান্য উত্তরে যোগদানের মতো )।
মার্কো রায়

1
@ মার্কোরোয় যা বলেছেন কেবল তার সাথে কিছু যুক্ত করার জন্য, যদি আপনার একই সর্বাধিক তারিখের সাথে একাধিক রেকর্ড থাকে, আপনি যদি ক্যোয়ারী পরিবর্তন করেন, যেমন আপনি এটি ডিবাগ করার সময়, একটি ভিন্ন রেকর্ড 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 কাজ করে না, অর্থাত্ এটি কোনও সাধারণ সমাধান নয়, যদিও বাম আউটর জয়েন্টের সাথে কাজ করার ধারণাটি গুরুত্বপূর্ণ এই উত্তরে জিনিস।
ersoncru

আকর্ষণীয়ভাবে যথেষ্ট, সাইবেস এএসই 16 ছোট (<10 কে সারি) টেবিলের জন্য সূক্ষ্ম কাজ করে, তবে বড়গুলি (> 100 কিলো সারি) এর সাথে এটি স্তব্ধ হয়ে যায় ... আমি ভেবেছিলাম যে এটিই উপযুক্ত উদাহরণটি হবে রিলেশনাল ডিবিগুলিকে এক্সেল করা উচিত ...
লিভেন্ট পাইড

1
@ শীর্ষস্থানীয় ... হ্যাঁ বামে যোগ দেওয়া বড় ডেটাসেটগুলিতে ব্যয়বহুল। যদি সম্ভব হয় তবে কোনওভাবেই এটি পরিচালনা করার জন্য আপনি ফিল্টার শর্তটি নিজেই যুক্ত করে একটি পারফরম্যান্স টুইট করতে পারেন।
সুজিত

20

ব্যবহারকারীর সর্বাধিক তারিখ সমেত পুরো সারিটি পেতে:

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

1
মাইএসকিউএল
স্কুল ছেলে

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
);

ROW_NUMBER

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 );
নর্শে

আমি উপস্থিত নেই বলে দেখেছি এবং এটি কেবলমাত্র তার বিপরীতে সমস্ত ব্যবহারকারীর উচ্চতর এন্ট্রি ফিরিয়ে দেবে বলে মনে হচ্ছে: "এমন একটি ক্যোয়ারী যা প্রতিটি ব্যবহারকারীর জন্য আমাকে সর্বশেষ তারিখ দেয়"।
তাসোস জেরভোস

আপনি সত্যিই সত্য, আমি আমার ক্যোয়ারী আপডেট। আপনার মন্তব্যের জন্য ধন্যবাদ! @ নরশ দুঃখিত, আমি কোনও কারণে আপনার মন্তব্যগুলি মিস করেছি: / তবে আপনি একেবারেই ঠিক বলেছেন।
ফ্যাবিয়ান পাইজেকে

2

এটি আপনার সম্পাদিত প্রশ্নের সঠিক ফলাফল দেবে should

সাব-কোয়েরিটি সর্বশেষতম তারিখের কেবল সারিগুলি সন্ধান করার বিষয়টি নিশ্চিত করে এবং বাইরের অংশটি 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 শে জানুয়ারীর আদেশ থাকলে কী হবে?
অহিগিন্স

আমি ব্যবহারকারীর নাম অনুসারে দলবদ্ধ করছি তাই এটি কাজ করবে এবং ফলাফলগুলি এর মতো হবে: ব্যবহারকারী নাম তারিখ মান বব 2010-02-02 1.2 ব্র্যাড 2010-02-02 1.4 ফ্রেড 2010-01-03 1.0
ওয়ারা

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

আমার টেবিলে থাকা প্রতিটি ব্যবহারকারীর সর্বশেষ রেকর্ড নিতে আমি এইভাবে ব্যবহার করেছি। PDA ডিভাইসগুলিতে সনাক্ত করা সাম্প্রতিক সময়ের হিসাবে বিক্রয়কর্মীর জন্য সর্বশেষ অবস্থানটি পাওয়া এটি ছিল একটি অনুসন্ধান।

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)

স্ট্যাকওভারফ্লোতে আপনাকে স্বাগতম এবং সহায়তা করার চেষ্টা করার জন্য ধন্যবাদ। আপনার মত কোড-উত্তরগুলি উত্তরগুলির তুলনায় কম প্রশংসা করা হয় যা সমাধান ব্যাখ্যা করে।
ইউনোশাচ

মানের উত্তর সরবরাহ করার জন্য দয়া করে এটি কীভাবে উত্তরটি পড়ুন।
ওয়েওওয়েওয়ের

এবং. এটি প্রতিটি ব্যবহারকারীর জন্য ম্যাক্সে ফিরে আসে না, কেবল সর্বশেষ একক সারিতে।
ইরভিনকাগু

0

আমার ছোট সংকলন

  • স্ব join নেস্টেড বেশী ভালোselect
  • কিন্তু আপনাকে group byদেয় নাprimary key , যার জন্য বাঞ্ছনীয়join
  • এই কীটি ( ডক্স)partition by এর সাথে একত্রে দেওয়া যেতে পারেfirst_value )

সুতরাং, এখানে একটি প্রশ্ন:

নির্বাচন করা
 টি। *
থেকে 
 টেবিল টি অভ্যন্তরীণ যোগদান (
  আইডি হিসাবে স্বতন্ত্র ফার্স্ট_ভ্যালু (আইডি) নির্বাচন করুন (তারিখ কলাম ডেস্ক দ্বারা গ্রুপকলাম ক্রমে বিভাজন)
  টেবিল থেকে
  যেখানে ফিল্টারকলাম = 'মান'
 ) জে টি.আইডি = জে.আইডি

পেশাদাররা:

  • যে whereকোনও কলাম ব্যবহার করে বিবৃতি সহ ডেটা ফিল্টার করুন
  • select ফিল্টারকৃত সারি থেকে কোনও কলাম

কনস:

  • এমএস এসকিউএল সার্ভারের 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

এটি উপরের উত্তরগুলির সাথে একটির মতো, তবে আমার মতে এটি অনেক সহজ এবং পরিপাটি। এছাড়াও, ক্রস প্রয়োগের বিবৃতিটির জন্য ভাল ব্যবহার দেখায়। এসকিউএল সার্ভার 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 এবং গ্রুপ দ্বারা ব্যবহার করবেন

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

7
আপনার সম্পাদনাটি এলোমেলোভাবে বেছে নেবে value, MAX(date)সারিটির সাথে সম্পর্কিত নয় ।
অ্যালিসন আর।

এটি সর্বোচ্চ তারিখ দেবে তবে ব্যবহারকারীর নাম এবং মান একই রেকর্ডের নাও হতে পারে।
এসকেআর
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.