এসকিউএল সার্ভার: কেবলমাত্র সর্বোচ্চ (DATE) সারি নির্বাচন করুন


109

আমার কাছে ডেটা টেবিল রয়েছে (ডিবি এমএসএসকিউএল):

    ID  OrderNO PartCode  Quantity DateEntered
    417 2144     44917    100      18-08-11
    418 7235     11762    5        18-08-11
    419 9999     60657    100      18-08-11
    420 9999     60657    90       19-08-11

আমি এমন একটি ক্যোয়ারী তৈরি করতে চাই যা অর্ডারনো, পার্টকোড এবং পরিমাণটি ফেরত দেয় তবে কেবলমাত্র শেষ নিবন্ধিত আদেশের জন্য।

উদাহরণ টেবিল থেকে আমি নিম্নলিখিত তথ্য ফিরে পেতে চাই:

     OrderNO PartCode  Quantity     
     2144     44917    100      
     7235     11762    5        
     9999     60657    90      

লক্ষ্য করুন যে কেবলমাত্র একটি লাইন 9999 অর্ডারে ফেরত ছিল।

ধন্যবাদ!


2
আপনার মন্তব্য থেকে, ROW_NUMBER () উত্তর সহ যান। এটি আরও দীর্ঘ দেখায়, তবে এটি আমার অভিজ্ঞতা অনুসারে উপযুক্ত সূচকগুলির সাথে খুব দ্রুত।
ম্যাটবাইলি

ধন্যবাদ ডেমস, আমি আপনার প্রচেষ্টার প্রশংসা করি।
GEMI

1
@ জিইএমআই কৌতূহলের বাইরে, MAX(DATE)9999 অর্ডারের জন্য একটি লাইন ফেরত দেয় না ?
জমির

হ্যাঁ, তবে আমি প্রতিটি পৃথক অর্ডার চেয়েছিলাম কেবলমাত্র শেষ আদেশের লাইনে return
GEMI

উত্তর:


184

যদি আপনার rownumber() over(...)জন্য উপলব্ধ থাকে ....

select OrderNO,
       PartCode,
       Quantity
from (select OrderNO,
             PartCode,
             Quantity,
             row_number() over(partition by OrderNO order by DateEntered desc) as rn
      from YourTable) as T
where rn = 1      

2
ধন্যবাদ মিকারেল এরিকসন, এটি একটি দুর্দান্ত প্রশ্ন!
জেমি

56

সেরা উপায় হ'ল মিকায়েল এরিকসন, যদি আপনার ROW_NUMBER()কাছে উপলব্ধ থাকে।

পরের সেরাটি হল কুলারিসের উত্তর অনুসারে কোনও প্রশ্নের সাথে যোগ দেওয়া।

বিকল্পভাবে, সর্বাধিক সহজ এবং সোজা এগিয়ে যাওয়ার উপায় হ'ল দফায় একটি সম্পর্কিত-সাব-কোয়েরি।

SELECT
  *
FROM
  yourTable AS [data]
WHERE
  DateEntered = (SELECT MAX(DateEntered) FROM yourTable WHERE orderNo = [data].orderNo)

অথবা ...

WHERE
  ID = (SELECT TOP 1 ID FROM yourTable WHERE orderNo = [data].orderNo ORDER BY DateEntered DESC)

29
select OrderNo,PartCode,Quantity
from dbo.Test t1
WHERE EXISTS(SELECT 1
         FROM dbo.Test t2
         WHERE t2.OrderNo = t1.OrderNo
           AND t2.PartCode = t1.PartCode
         GROUP BY t2.OrderNo,
                  t2.PartCode
         HAVING t1.DateEntered = MAX(t2.DateEntered))

এটি উপরে সরবরাহিত সমস্ত প্রশ্নের মধ্যে দ্রুততম। ক্যোয়ারী ব্যয়টি 0.0070668 এ এসেছিল।

মিকেল এরিকসনের উপরের পছন্দের উত্তরের একটি ক্যোয়ারির মূল্য 0.0146625

আপনি এই জাতীয় ছোট নমুনার জন্য পারফরম্যান্সের বিষয়ে চিন্তা করতে পারেন না তবে বড় প্রশ্নগুলিতে এটি সমস্ত কিছু যুক্ত হয়।


2
এটি আমার কাছে এখানে অন্যান্য সমাধানগুলির তুলনায় একটি ~ 3.5M সারি ডেটাসেটের তুলনায় সামান্য দ্রুত পরিণত হয়েছিল, তবে এসএসএমএস একটি সূচক প্রস্তাব করেছিল যা কার্যকর করার সময়টিকে অর্ধেক করে দেয় cut ধন্যবাদ!
ইশুটার

দ্রুত এবং সোজা। ধন্যবাদ।
স্টিফেন জেং

আমার 100k সারি রয়েছে এবং আমার জন্য মিকেল এরিকসনের ক্যোয়ারি 3 গুন দ্রুত। সম্ভবত এটি কারণ আমি ধারা দ্বারা বিভাজনে রাউন্ড ফাংশন করেছি।
ওয়াচবার্ন

আপনার যদি 2 টি ভিন্ন ভিন্ন আইডির জন্য একই মান (04/15/2017) সহ একটি তারিখের ক্ষেত্র থাকে, তবে এটি 2 সারি ফিরে আসবে ...
পোর্তেকোই

হ্যাঁ পোর্তেকোই, এটি সত্য, তবে দুটি সারি আলাদা করার কোনও উপায় ছাড়াই আপনি কীভাবে অন্যটির উপরে একটি নির্বাচন করতে পারেন? আপনি ফলাফলের উপরে একটি শীর্ষস্থানীয় রাখতে পারেন, তবে আপনি কীভাবে জানবেন যে এটি আপনি চাইছেন এমন অন্য সারিতে নয়?
স্বন

10
SELECT t1.OrderNo, t1.PartCode, t1.Quantity
FROM table AS t1
INNER JOIN (SELECT OrderNo, MAX(DateEntered) AS MaxDate
            FROM table
            GROUP BY OrderNo) AS t2
ON (t1.OrderNo = t2.OrderNo AND t1.DateEntered = t2.MaxDate)

অভ্যন্তরীণ ক্যোয়ারী OrderNoতাদের সর্বোচ্চ তারিখের সাথে সমস্ত নির্বাচন করে । টেবিলের অন্যান্য কলামগুলি পেতে, আপনি এগুলিতে OrderNoএবং এর সাথে যোগ দিতে পারেন MaxDate


1

মাইএসকিউএল এর জন্য আপনি নীচের মতো কিছু করতে পারেন:

select OrderNO, PartCode, Quantity from table a
join (select ID, MAX(DateEntered) from table group by OrderNO) b on a.ID = b.ID

অর্ডার নং
জ্যাকব

@ ডেমস ধন্যবাদ @ কুলারিস হ্যাঁ, এটি মাইএসকিএল-কে উল্লেখ করছে, প্রশ্নটি কোন ডাটাবেস ইঞ্জিনটি নির্দিষ্ট করে নি
বেনকবব

আপনি যদি কোড, এক্সএমএল বা ডেটা নমুনাগুলি পোস্ট করেন তবে দয়া করে টেক্সট সম্পাদকের সেই লাইনগুলি হাইলাইট { }করুন এবং এডিটর টুলবারের "কোড স্যাম্পল" বোতামটিতে ক্লিক করুন: সুন্দরভাবে ফর্ম্যাট করতে এবং সিনট্যাক্সটিকে হাইলাইট করুন!
marc_s

এটি এমএসএসকিউএল, এর জন্য দুঃখিত।
GEMI

1

এবং আপনি সেই নির্বাচিত বিবৃতিটি বাম যোগ যোগদানের ক্যোয়ারী হিসাবেও ব্যবহার করতে পারেন ... উদাহরণ:

... left join (select OrderNO,
   PartCode,
   Quantity from (select OrderNO,
         PartCode,
         Quantity,
         row_number() over(partition by OrderNO order by DateEntered desc) as rn
  from YourTable) as T where rn = 1 ) RESULT on ....

আশা করি এটি এমন কাউকে সহায়তা করবে যা এটি অনুসন্ধান করবে :)


1

rownumber () over (...) কাজ করছে তবে আমি 2 কারণে এই সমাধানটি পছন্দ করি না। - আপনি এসকিউএল 2000 এর মতো এসকিউএল এর পুরানো সংস্করণ ব্যবহার করার সময় এই ফাংশনটি উপলভ্য হয় না function ফাংশনের উপর নির্ভরতা এবং সত্যই পঠনযোগ্য নয়।

আর একটি সমাধান হ'ল:

SELECT tmpall.[OrderNO] ,
       tmpall.[PartCode] ,
       tmpall.[Quantity] ,
FROM   (SELECT [OrderNO],
               [PartCode],
               [Quantity],
               [DateEntered]
        FROM   you_table) AS tmpall
       INNER JOIN (SELECT [OrderNO],
                          Max([DateEntered]) AS _max_date
                   FROM   your_table
                   GROUP  BY OrderNO ) AS tmplast
               ON tmpall.[OrderNO] = tmplast.[OrderNO]
                  AND tmpall.[DateEntered] = tmplast._max_date

1

আপনার যদি ইনডেক্সড আইডি এবং অর্ডার নেই তবে আপনি ইন ব্যবহার করতে পারেন: (আমি কেবল কিছু চক্র বাঁচাতে অস্পষ্টতার জন্য ব্যবসায়ের সরলতাকে ঘৃণা করি):

select * from myTab where ID in(select max(ID) from myTab group by OrderNo);

0

ব্যবহার যোগ দিন এড়ানোর চেষ্টা করুন

SELECT SQL_CALC_FOUND_ROWS *  FROM (SELECT  msisdn, callid, Change_color, play_file_name, date_played FROM insert_log
   WHERE play_file_name NOT IN('Prompt1','Conclusion_Prompt_1','silent')
 ORDER BY callid ASC) t1 JOIN (SELECT MAX(date_played) AS date_played FROM insert_log GROUP BY callid) t2 ON t1.date_played=t2.date_played

1
কেন এড়ানো হবে? আপনার মতামত সমর্থন করার জন্য আপনার কি কোনও যুক্তি আছে?
প্রিজা

এটি আপনার ক্যোয়ারীটি কার্যকর করতে দীর্ঘ সময় নিবে। আপনি নিম্নলিখিত নিবন্ধটি পড়তে পারেন xaprb.com/blog/2006/06/28/why-large-in-clauses-are-problematic
কিং নিও

@ অনিক এটি ২০০ 2006 সালের একটি নিবন্ধ you আপনি যা বলছেন তার কোনও সাম্প্রতিক প্রমাণ কি আপনার কাছে রয়েছে?
ফলিক্স গ্যাগন-গ্রেনিয়ার

0

এটি আমার পক্ষে পুরোপুরি ঠিক আছে।

    select name, orderno from (
         select name, orderno, row_number() over(partition by 
           orderno order by created_date desc) as rn from orders
    ) O where rn =1;

-1

এটি আমার পক্ষে কাজ করে। ব্যবহারের MAX টি (রূপান্তর করুন (তারিখ, ReportDate)) নিশ্চিত করুন যে আপনি তারিখ মূল্য আছে করতে

select max( CONVERT(date, ReportDate)) FROM [TraxHistory]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.