প্রতিটি বিভাগের জন্য শীর্ষ 10 রেকর্ড নির্বাচন করুন


207

আমি এক ক্যোয়ারিতে প্রতিটি বিভাগ থেকে শীর্ষ 10 রেকর্ড ফিরিয়ে দিতে চাই। কেউ কীভাবে এটি করতে সাহায্য করতে পারে? বিভাগটি টেবিলের কলামগুলির মধ্যে একটি।

ডাটাবেসটি এসকিউএল সার্ভার ২০০৫ date বিভাগগুলি হ'ল ব্যবসায়, স্থানীয় এবং বৈশিষ্ট্য। একটি নির্দিষ্ট তারিখের জন্য আমি কেবল শীর্ষ (10) ব্যবসায়িক সারি (অতি সাম্প্রতিক প্রবেশ), শীর্ষ (10) স্থানীয় সারি এবং শীর্ষ (10) বৈশিষ্ট্য চাই।


এই উত্তরগুলির কোনও আপনার পক্ষে কাজ করে?
কাইল

3
আমি অনুমান করি আমরা কখনই জানতে পারব না ...
ডেনি

এটি 12 বছর হয়েছে এবং আমরা জানি না যে তাদের কোনও কাজ করেছে কিনা।
সুগন্ধ

উত্তর:


221

আপনি যদি এসকিউএল 2005 ব্যবহার করে থাকেন তবে আপনি এই জাতীয় কিছু করতে পারেন ...

SELECT rs.Field1,rs.Field2 
    FROM (
        SELECT Field1,Field2, Rank() 
          over (Partition BY Section
                ORDER BY RankCriteria DESC ) AS Rank
        FROM table
        ) rs WHERE Rank <= 10

যদি আপনার র্যাঙ্কক্রিটায়ার সাথে সম্পর্ক থাকে তবে আপনি 10 টিরও বেশি সারি ফিরে আসতে পারেন এবং ম্যাট এর সমাধানটি আপনার পক্ষে ভাল be


31
আপনি যদি সত্যিই শীর্ষস্থানীয় 10 চান তবে এটিকে র্যাঙ্ক () এর পরিবর্তে RowNumber () এ পরিবর্তন করুন। কোন সম্পর্ক নেই।
মাইক এল

3
এটি কাজ করে তবে সচেতন হন যে র‌্যাঙ্ক () প্রথমে কী সূচকটি র‌্যাঙ্কক্রিটরিয়া নয় এমন কোনও সূচক না থাকলে কোয়েরি পরিকল্পনাকারীর দ্বারা পুরো টেবিল সাজানোর ক্ষেত্রে রূপান্তরিত হতে পারে । এই ক্ষেত্রে আপনি পৃথক বিভাগগুলি নির্বাচন করে আরও ভাল মাইলেজ পেতে পারেন এবং র্যাঙ্কক্রিটরিয়া ডেস্কের আদেশ অনুসারে শীর্ষস্থানীয় 10 বাছাইয়ের জন্য আবেদন করতে পারেন।
জো কেয়ার্নি

দুর্দান্ত উত্তর! আমার যা প্রয়োজন ঠিক তা পেয়েছি G আমি শেষ করেছি DENSE_RANKযার সাথে সংখ্যার কোনও ফাঁক নেই। +1
মাইকেল স্ট্র্যামেল

1
@ ফ্যাকবড এটি টেবিলে কেবল একটি উপনাম।
ড্যারেল মিলার 4'14

15
যে কেউ স্কেল সার্ভার ব্যবহার করে তার জন্য, মাইক এল দ্বারা উল্লিখিত RowNumber () ফাংশনটি ROW_NUMBER ()।
র্যান্ডমরাক্কুন

99

টি-এসকিউএলে, আমি এটি করব:

WITH TOPTEN AS (
    SELECT *, ROW_NUMBER() 
    over (
        PARTITION BY [group_by_field] 
        order by [prioritise_field]
    ) AS RowNo 
    FROM [table_name]
)
SELECT * FROM TOPTEN WHERE RowNo <= 10

2
: দয়া করে আপনার সমাধান সম্পর্কে আরও বর্ণনামূলক হন। উল্লেখ করুন: কীভাবে উত্তর দিন

সিটিইতে নির্বাচন করা কোয়েরিতে কোথাও ধারা থাকতে পারে?
তোহা

1
@ তোহা হ্যাঁ এটি করতে পারে
কিন্ডা টেকি

1
যদিও আপনি "ইন টি-এসকিউএল" বলছেন এটি কোনও ROW_NUMBERফাংশন প্রয়োগকারী ডাটাবেসের জন্য কাজ করে। উদাহরণস্বরূপ, আমি এসকিউএলাইটে এই সমাধানটি ব্যবহার করেছি।
টনি

এটি পোস্টগ্রিস স্কিলের জন্যও কাজ করে। আমাকে সবেমাত্র "[অগ্রাধিকার_ফিল্ড] ডেস্কের মাধ্যমে" অর্ডার ব্যবহার করতে হয়েছিল
ফুন

35

এটি এসকিউএল সার্ভার 2005-এ কাজ করে (আপনার স্পষ্টকরণের প্রতিবিম্বিত করতে সম্পাদিত):

select *
from Things t
where t.ThingID in (
    select top 10 ThingID
    from Things tt
    where tt.Section = t.Section and tt.ThingDate = @Date
    order by tt.DateEntered desc
    )
    and t.ThingDate = @Date
order by Section, DateEntered desc

2
যদিও বিভাগটি শূন্য রয়েছে সারিগুলির জন্য এটি কাজ করে না। আপনাকে বলতে হবে "যেখানে (টিটি। সেকশনটি নাল এবং টি। সেকশন নাল) বা টিটি.সেকশন = টি.সেকশন"
ম্যাট হ্যামিল্টন

29
SELECT r.*
FROM
(
    SELECT
        r.*,
        ROW_NUMBER() OVER(PARTITION BY r.[SectionID] ORDER BY r.[DateEntered] DESC) rn
    FROM [Records] r
) r
WHERE r.rn <= 10
ORDER BY r.[DateEntered] DESC

ওরফে 'এম' দিয়ে টেবিল কী?
চক্কি

@ চক্কি এটা টাইপো, হওয়া উচিত r। স্থির করেছি।
লরন্ড

কবজির মতো কাজ করেছেন। ধন্যবাদ!
রন নুনি

18

আমি এটি এইভাবে করি:

SELECT a.* FROM articles AS a
  LEFT JOIN articles AS a2 
    ON a.section = a2.section AND a.article_date <= a2.article_date
GROUP BY a.article_id
HAVING COUNT(*) <= 10;

আপডেট: গ্রুপ বাই এর এই উদাহরণটি কেবল মাইএসকিউএল এবং এসকিউএলাইটে কাজ করে, কারণ সেই ডাটাবেসগুলি গ্রুপের মাধ্যমে স্ট্যান্ডার্ড এসকিউএল এর চেয়ে বেশি অনুমোদিত। বেশিরভাগ এসকিউএল বাস্তবায়নের জন্য আবশ্যক যে নির্বাচনের তালিকার সমস্ত কলাম যা সামগ্রিক অভিব্যক্তির অংশ নয়, এছাড়াও গ্রুপের মাধ্যমে রয়েছে।


1
ওইটা কি কাজ করে? আমি অবশ্যই নিশ্চিত যে আপনি "a.omeomecolumn নির্বাচন তালিকাটিতে অবৈধ কারণ এটি একটি সামগ্রিক ফাংশনে বা গ্রুপের সাথে দফা অনুসারে গ্রুপে অন্তর্ভুক্ত নেই" নিবন্ধের প্রতিটি নিবন্ধের নিবন্ধের নিবন্ধ ছাড়া ..
ব্লগারবার্ড

1
GROUP BY- তে নামযুক্ত কলাম (গুলি) এর উপর কার্যত নির্ভরশীল অন্যান্য কলামগুলি আপনার অন্তর্ভুক্ত করতে সক্ষম হওয়া উচিত। কার্যকরীভাবে নির্ভরশীল নয় এমন কলামগুলি অস্পষ্ট। তবে আপনি ঠিক বলেছেন, আরডিবিএমএস বাস্তবায়নের উপর নির্ভর করে। এটি মাইএসকিউএলে কাজ করে তবে আইআইআরসি ইন্টারবেস / ফায়ারবার্ডে ব্যর্থ হয়।
বিল কারউইন

1
এই বিভাগটি কী কাজ করবে যে কোনও বিভাগের শীর্ষ এগারোটি রেকর্ডের একই তারিখ ছিল? তাদের সকলের 11 টি গণনা হবে এবং ফলাফলটি খালি সেট হবে।
আর্থ

না, আপনার সকলের একই তারিখ থাকলে সম্পর্ক ছিন্ন করার কিছু উপায় থাকা দরকার। উদাহরণস্বরূপ stackoverflow.com/questions/121387/… দেখুন ।
বিল কারভিন

1
@ কার্লোসগ, নিবন্ধগুলির বিভাগগুলির সাথে যদি একাধিক থেকে অনেকের সম্পর্ক থাকে, তবে নিবন্ধগুলি তাদের বিভাগগুলিতে মানচিত্র করার জন্য আপনার একটি ছেদ টেবিলের প্রয়োজন। তারপরে আপনার ক্যোয়ারিতে এম 2 মিটার সম্পর্কের জন্য ছেদ টেবিলের সাথে যুক্ত হতে হবে এবং নিবন্ধ_আইডি এবং বিভাগ অনুসারে গ্রুপ করুন। এটি আপনাকে শুরু করা উচিত, তবে আমি কোনও মন্তব্যে পুরো সমাধানটি লিখতে যাচ্ছি না।
বিল কারভিন

16

যদি আমরা এসকিউএল সার্ভার> = 2005 ব্যবহার করি তবে আমরা কেবলমাত্র একটি নির্বাচন দিয়ে কাজটি সমাধান করতে পারি :

declare @t table (
    Id      int ,
    Section int,
    Moment  date
);

insert into @t values
(   1   ,   1   , '2014-01-01'),
(   2   ,   1   , '2014-01-02'),
(   3   ,   1   , '2014-01-03'),
(   4   ,   1   , '2014-01-04'),
(   5   ,   1   , '2014-01-05'),

(   6   ,   2   , '2014-02-06'),
(   7   ,   2   , '2014-02-07'),
(   8   ,   2   , '2014-02-08'),
(   9   ,   2   , '2014-02-09'),
(   10  ,   2   , '2014-02-10'),

(   11  ,   3   , '2014-03-11'),
(   12  ,   3   , '2014-03-12'),
(   13  ,   3   , '2014-03-13'),
(   14  ,   3   , '2014-03-14'),
(   15  ,   3   , '2014-03-15');


-- TWO earliest records in each Section

select top 1 with ties
    Id, Section, Moment 
from
    @t
order by 
    case 
        when row_number() over(partition by Section order by Moment) <= 2 
        then 0 
        else 1 
    end;


-- THREE earliest records in each Section

select top 1 with ties
    Id, Section, Moment 
from
    @t
order by 
    case 
        when row_number() over(partition by Section order by Moment) <= 3 
        then 0 
        else 1 
    end;


-- three LATEST records in each Section

select top 1 with ties
    Id, Section, Moment 
from
    @t
order by 
    case 
        when row_number() over(partition by Section order by Moment desc) <= 3 
        then 0 
        else 1 
    end;

1
+1 আমি সরলতার জন্য এই সমাধানটি পছন্দ করি তবে আপনি কী ব্যাখ্যা করতে পারবেন যে ক্লোজটিতে স্টেটমেন্টটি 0 বা 1 ফেরত top 1দিয়ে কীভাবে কাজ করে ? caseorder by
সেরেস

3
শীর্ষ 1 এখানে টাইসের সাথে কাজ করে। সংঘের সাথে অর্থ দাঁড়ায় যে যখন অর্ডার বাই = 0, তখন নির্বাচন করুন এই রেকর্ডটি নেয় (শীর্ষ 1 এর কারণে) এবং অন্য সকলের কাছে অর্ডার BY = 0 (
সংযোগের

9

আপনি যদি বিভাগগুলি কী জানেন তবে আপনি এটি করতে পারেন:

select top 10 * from table where section=1
union
select top 10 * from table where section=2
union
select top 10 * from table where section=3

3
এটি করার সহজ উপায় এটি হবে।
হেক্টর সোসা জুনিয়র

3
তবে এটি অদক্ষ হবে যদি আপনার 150 থাকে বা বিভাগ, দিন, সপ্তাহ ইত্যাদি অনুসারে পরিবর্তনশীল হয়
রাফা ব্যারাগান

1
অবশ্যই, তবে ওপিকে উদ্ধৃত করার জন্য: "বিভাগগুলি হ'ল ব্যবসায়, স্থানীয় এবং বৈশিষ্ট্য"। আপনার যদি তিনটি স্থিতিশীল বিভাগ থাকে তবে এটি করার সেরা উপায় এটি।
ব্লারগবার্ড

9

আমি জানি যে এই থ্রেডটি খানিকটা পুরানো তবে আমি সবেমাত্র একটি অনুরূপ সমস্যায় পড়েছি (প্রতিটি বিভাগ থেকে নতুন নিবন্ধটি নির্বাচন করুন) এবং এটিই সমাধানটি আমি এনেছি:

WITH [TopCategoryArticles] AS (
    SELECT 
        [ArticleID],
        ROW_NUMBER() OVER (
            PARTITION BY [ArticleCategoryID]
            ORDER BY [ArticleDate] DESC
        ) AS [Order]
    FROM [dbo].[Articles]
)
SELECT [Articles].* 
FROM 
    [TopCategoryArticles] LEFT JOIN 
    [dbo].[Articles] ON
        [TopCategoryArticles].[ArticleID] = [Articles].[ArticleID]
WHERE [TopCategoryArticles].[Order] = 1

এটি ড্যারেলের সমাধানের সাথে খুব অনুরূপ তবে র্যাঙ্ক সমস্যাটি কাটিয়ে উঠেছে যা উদ্দেশ্য থেকে আরও সারি ফিরে আসতে পারে।


সিটিই স্যার কেন ব্যবহার করবেন? এটি কি স্মৃতিশক্তি খরচ কমায়?
তোহা

@ তোহা কারণ সিটিইগুলি সহজ এবং বোঝার পক্ষে সহজ
বিপরীত প্রকৌশলী

দুর্দান্ত উত্তর !! এটি এর JOINপরিবর্তে অভ্যন্তরীণ ব্যবহার করে অনুকূলিত করা যেতে পারে LEFT JOIN, কারণ এর TopCategoryArticlesসাথে সম্পর্কিত Articleরেকর্ড ছাড়া কোনও রেকর্ড থাকবে না ।
উল্টো ইঞ্জিনিয়ার

6

নিম্নলিখিত চেষ্টা করে দেখুন এবং এটি বন্ধনের সাথেও কাজ করে।

SELECT rs.Field1,rs.Field2 
FROM (
    SELECT Field1,Field2, ROW_NUMBER() 
      OVER (Partition BY Section
            ORDER BY RankCriteria DESC ) AS Rank
    FROM table
    ) rs WHERE Rank <= 10

5

আপনি অধ্যায় দ্বারা গ্রুপকৃত আউটপুট উত্পাদন, শুধুমাত্র উপরের প্রদর্শন করার চান এন ভালো প্রতিটি বিভাগে কিছু থেকে রেকর্ড:

SECTION     SUBSECTION

deer        American Elk/Wapiti
deer        Chinese Water Deer
dog         Cocker Spaniel
dog         German Shephard
horse       Appaloosa
horse       Morgan

... তারপরে নিম্নলিখিত সমস্ত এসকিউএল ডাটাবেসগুলির সাথে বেশ সাধারণভাবে কাজ করা উচিত। আপনি যদি শীর্ষ 10 চান তবে ক্যোয়ারির শেষের দিকে 2 থেকে 10 এ পরিবর্তন করুন।

select
    x1.section
    , x1.subsection
from example x1
where
    (
    select count(*)
    from example x2
    where x2.section = x1.section
    and x2.subsection <= x1.subsection
    ) <= 2
order by section, subsection;

স্থাপন করতে:

create table example ( id int, section varchar(25), subsection varchar(25) );

insert into example select 0, 'dog', 'Labrador Retriever';
insert into example select 1, 'deer', 'Whitetail';
insert into example select 2, 'horse', 'Morgan';
insert into example select 3, 'horse', 'Tarpan';
insert into example select 4, 'deer', 'Row';
insert into example select 5, 'horse', 'Appaloosa';
insert into example select 6, 'dog', 'German Shephard';
insert into example select 7, 'horse', 'Thoroughbred';
insert into example select 8, 'dog', 'Mutt';
insert into example select 9, 'horse', 'Welara Pony';
insert into example select 10, 'dog', 'Cocker Spaniel';
insert into example select 11, 'deer', 'American Elk/Wapiti';
insert into example select 12, 'horse', 'Shetland Pony';
insert into example select 13, 'deer', 'Chinese Water Deer';
insert into example select 14, 'deer', 'Fallow';

যখন আমি প্রতিটি বিভাগের জন্য প্রথম রেকর্ড চাই তখন এটি কাজ করে না। এটি 1 টিরও বেশি রেকর্ডযুক্ত সমস্ত বিভাগের গোষ্ঠীগুলি দূর করে। আমি <= 2 এর পরিবর্তে <= 1
শনিবার

@ নিলগুলি কেবলমাত্র তিনটি বিভাগের মান রয়েছে: হরিণ, কুকুর এবং ঘোড়া। যদি আপনি <= 1 এ ক্যোয়ারীটি পরিবর্তন করেন তবে আপনি প্রতিটি বিভাগের জন্য একটি উপশক্তি পাবেন: হরিণের জন্য আমেরিকান এলক / ওয়াপিটি, কুকুরের জন্য ককার স্প্যানিয়েল এবং ঘোড়ার জন্য অ্যাপালুসা। বর্ণমালা অনুসারে এগুলিও প্রতিটি বিভাগের প্রথম মান। ক্যোয়ারীটি অন্য সমস্ত মানগুলি মুছে ফেলার জন্য বোঝানো হয়েছে।
ক্রেগ

তবে আমি যখন আপনার ক্যোয়ারী চালানোর চেষ্টা করি তখন এটি সমস্ত কিছু সরিয়ে দেয় কারণ সমস্ত কিছুর জন্য গণনা> = 1। এটি প্রতিটি বিভাগের জন্য প্রথম অনুচ্ছেদ সংরক্ষণ করে না। আপনি কি <= 1 এর জন্য আপনার ক্যোয়ারী চালানোর চেষ্টা করতে পারেন এবং যদি আপনি প্রতিটি বিভাগের জন্য প্রথম উপ-বিভাগ পেয়ে থাকেন তবে আমাকে জানান?
Nils

@ নিলস হাই, আমি স্ক্রিপ্টগুলি থেকে এই ছোট্ট পরীক্ষার ডাটাবেসটি পুনরায় তৈরি করেছি এবং <= 1 ব্যবহার করে ক্যোয়ারী চালিয়েছি এবং এটি প্রতিটি বিভাগ থেকে প্রথম উপ-অনুচ্ছেদের মানটি ফিরিয়ে দিয়েছে। আপনি কোন ডাটাবেস সার্ভার ব্যবহার করছেন? আপনার পছন্দের ডেটাবেজের সাথে সম্পর্কিত এমন একটি সুযোগ সর্বদা থাকে। আমি এটি মাইএসকিউএলে চালিয়েছি কারণ এটি সুবিধাজনক ছিল এবং এটি প্রত্যাশার মতো আচরণ করে। আমি প্রথম নিশ্চিত হয়েছি যখন আমি প্রথমবার এটি করেছি (আমি নিশ্চিত হয়েছি যে আমি যা পোস্ট করেছি তা ডিবাগিন ছাড়াই আসলে কী কাজ করেছে), আমি নিশ্চিত যে আমি যে কোনও জায়গায় সিবাজ এসকিউএল বা এমএস এসকিউএল সার্ভার ব্যবহার করে এটি করেছি।
ক্রেগ

এটি MySQL এ আমার জন্য পুরোপুরি কাজ করেছিল। আমি একটি কোয়েরিটি কিছুটা পরিবর্তিত করে নিশ্চিত হয়েছি কেন তিনি << সাবচেকশনটিতে বার্চর ক্ষেত্রের জন্য ব্যবহার করেছিলেন .. আমি এটিকে এবং x2.subsection = x1.sussection- এ পরিবর্তন করেছি
মাহেন

4

পারে ইউনিয়ন তোমার জন্য অপারেটর কাজ করে? প্রতিটি বিভাগের জন্য একটি নির্বাচন করুন, তারপরে তাদের একসাথে ইউনিয়ন করুন। অনুমান করুন এটি কেবলমাত্র নির্দিষ্ট সংখ্যক বিভাগের জন্য কাজ করবে।


4

প্রশ্ন) প্রতিটি গ্রুপ থেকে শীর্ষ এক্স রেকর্ড সন্ধান করা (ওরাকল)

SQL> select * from emp e 
  2  where e.empno in (select d.empno from emp d 
  3  where d.deptno=e.deptno and rownum<3)
  4  order by deptno
  5  ;

 EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO

  7782 CLARK      MANAGER         7839 09-JUN-81       2450                    10
  7839 KING       PRESIDENT            17-NOV-81       5000                    10
  7369 SMITH      CLERK           7902 17-DEC-80        800                    20
  7566 JONES      MANAGER         7839 02-APR-81       2975                    20
  7499 ALLEN      SALESMAN        7698 20-FEB-81       1600        300         30
  7521 WARD       SALESMAN        7698 22-FEB-81       1250        500         30

6 টি সারি নির্বাচন করা হয়েছে।



প্রশ্নটি এসকিউএল সার্ভার সম্পর্কে ছিল, ওরাকল নয়।
ক্রেগ

2

প্রশ্ন SQL সার্ভার 2005 সম্পর্কে ছিল না, তাই অধিকাংশ মানুষের উপর সরানো হয়েছে এবং যদি তারা এই প্রশ্নের খুঁজে পাব, কি হতে পারে অন্যান্য পরিস্থিতিতে পছন্দের উত্তর এক ব্যবহার CROSS APPLYএই ব্লগ পোস্টে দেখানো হিসাবে

SELECT *
FROM t
CROSS APPLY (
  SELECT TOP 10 u.*
  FROM u
  WHERE u.t_id = t.t_id
  ORDER BY u.something DESC
) u

এই ক্যোয়ারিতে 2 টি সারণী জড়িত। ওপির ক্যোয়ারিতে কেবলমাত্র 1 টি টেবিল জড়িত, যদি উইন্ডো ফাংশন ভিত্তিক সমাধানটি আরও কার্যকর হতে পারে সে ক্ষেত্রে।


1

আপনি এই পদ্ধতির চেষ্টা করতে পারেন। এই ক্যোয়ারি প্রতিটি দেশের জন্য সবচেয়ে বেশি জনবহুল 10 টি শহর ফেরত দেয়।

   SELECT city, country, population
   FROM
   (SELECT city, country, population, 
   @country_rank := IF(@current_country = country, @country_rank + 1, 1) AS country_rank,
   @current_country := country 
   FROM cities
   ORDER BY country, population DESC
   ) ranked
   WHERE country_rank <= 10;

9 টি সমান জনসংখ্যার সাথে এক দেশের রেকর্ডযুক্ত একটি টেবিল থাকে যখন এই সমাধানটি পরীক্ষার কেসটি পাস করে না উদাহরণস্বরূপ এটি সমস্ত 9 টি উপলব্ধ রেকর্ডকে ক্রমানুসারে ফিরিয়ে দেওয়ার পরিবর্তে বাতিল করে দেয়। এই সমস্যা সমাধানের জন্য কোনও পরামর্শ?
মোজগান মাজনচি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.