প্রতিটি গ্রুপের প্রথম সারিটি কীভাবে নির্বাচন করবেন?


57

আমার এই মত একটি টেবিল আছে:

 ID |  Val   |  Kind
----------------------
 1  |  1337  |   2
 2  |  1337  |   1
 3  |   3    |   4
 4  |   3    |   4

আমি এমন একটি তৈরি করতে চাই SELECTযা প্রতিটিটির জন্য কেবল প্রথম সারিতে ফিরে আসবে Val, অর্ডার দিয়ে Kind

নমুনা আউটপুট:

 ID |  Val   |  Kind
----------------------
 2  |  1337  |   1
 3  |   3    |   4

আমি এই কোয়েরিটি কীভাবে তৈরি করতে পারি?


কেন 3 | 3 | 4 এবং 4 | 3 | 4 - টাই-ব্রেক কি বা আপনার যত্ন নেই?
জ্যাক ডগলাস

@ জ্যাকডুগলাস আসলে আমার কাছে একটি আছে ORDER BY ID DESC, তবে এটি প্রশ্নের জন্য প্রাসঙ্গিক নয়। এই উদাহরণে আমি যত্ন নেই।
ব্রুনোএলএম

উত্তর:


38

এই সমাধানটি ব্যবহার করে keep, তবে valএবং kindসাব-কোয়েরি ছাড়াই প্রতিটি গ্রুপের জন্য সহজেই গণনা করা যেতে পারে:

select min(id) keep(dense_rank first order by kind) id
     , val
     , min(kind) kind
  from mytable
 group by val;
আইডি | ভ্যাল | ধরনের
-: | ---: | ---:
 3 | 3 | 4
 2 | 1337 | 1

এখানে ডিবিফিডল

KEEP… FIRST এবং KEEP… সর্বশেষের সামগ্রীর একটি ওরাকল-নির্দিষ্ট বৈশিষ্ট্য - আপনি তারপরে এখানে ওরাকল ডক্সে বা ওআরএসিএল_বিএসএতে পড়তে পারেন :

প্রথম এবং শেষ মানটি আদেশযুক্ত ক্রম থেকে প্রথম বা শেষ মানটি ফেরত দিতে ব্যবহার করা যেতে পারে


62

একটি সাধারণ টেবিল এক্সপ্রেশন (সিটিই) এবং একটি উইন্ডো / র‌্যাঙ্কিং / পার্টিশন ফাংশন যেমন ROW_NUMBER ব্যবহার করুন

এই প্রশ্নের সাথে আদেশ নামক একটি ইন-মেমোরি সারণি তৈরি এবং আরএন একটি অতিরিক্ত কলামে 1 থেকে সংখ্যার একটি ক্রম এন হয় যোগ করা হবে পার্টিশন বাই ইঙ্গিত এটা 1 প্রত্যেক সময় Val, পরিবর্তনের মান পুনঃসূচনা করা উচিত এবং আমরা অর্ডার দিতে চাই প্রকারের ক্ষুদ্রতম মান অনুসারে সারিগুলি।

WITH ORDERED AS
(
SELECT
    ID
,   Val
,   kind
,   ROW_NUMBER() OVER (PARTITION BY Val ORDER BY Kind ASC) AS rn
FROM
    mytable
)
SELECT
    ID
,   Val
,   Kind
FROM
    ORDERED
WHERE
    rn = 1;

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


25

বিলিঙ্কস এর সমাধানটি ভাল কাজ করে, তবে আমি ভেবেছিলাম আমারও টাস আউট করতে হবে। এটির একই ব্যয় রয়েছে তবে এটি দ্রুত হতে পারে (বা ধীর, আমি এটি পরীক্ষা করে দেখিনি)। পার্থক্যটি হ'ল এটি রো-নাম্বারের পরিবর্তে ফার্স্ট_ভ্যালু ব্যবহার করে। যেহেতু আমরা কেবল প্রথম মানটিতে আগ্রহী তাই আমার মনে এটি আরও সহজ।

SELECT ID, Val, Kind FROM
(
   SELECT First_Value(ID) OVER (PARTITION BY Val ORDER BY Kind) First, ID, Val, Kind 
   FROM mytable
)
WHERE ID = First;

পরীক্ষার ডেটা।

--drop table mytable;
create table mytable (ID Number(5) Primary Key, Val Number(5), Kind Number(5));

insert into mytable values (1,1337,2);
insert into mytable values (2,1337,1);
insert into mytable values (3,3,4);
insert into mytable values (4,3,4);

আপনি যদি পছন্দ করেন তবে এখানে সিটিই সমতুল্য।

WITH FirstIDentified AS (
   SELECT First_Value(ID) OVER (PARTITION BY Val ORDER BY Kind) First, ID, Val, Kind 
   FROM mytable
   )
SELECT ID, Val, Kind FROM FirstIdentified
WHERE ID = First;

1
+1 তবে আমি কেবল এটি জোর দিয়েই মূল্যবান মনে করেছি যে আপনার উত্তর এবং বিলিংকগুলি idঅনন্য না হলে যুক্তিযুক্তভাবে একই নয় ।
জ্যাক ডগলাস

@ জ্যাক ডগলাস - সত্য, আমি ধরে নিয়েছি।
লেইফ রিফেল

14

আপনি প্রতিটি গ্রুপ থেকে keepএকটি নির্বাচন করতে ব্যবহার করতে পারেন id:

select *
from mytable
where id in ( select min(id) keep (dense_rank first order by kind, id)
              from mytable
              group by val );
আইডি | ভ্যাল | ধরনের
-: | ---: | ---:
 2 | 1337 | 1
 3 | 3 | 4

এখানে ডিবিফিডল


2
SELECT MIN(MyTable01.Id) as Id,
       MyTable01.Val     as Val,
       MyTable01.Kind    as Kind 
  FROM MyTable MyTable01,                         
       (SELECT Val,MIN(Kind) as Kind
          FROM MyTable                   
      GROUP BY Val) MyTableGroup
WHERE MyTable01.Val  = MyTableGroup.Val
  AND MyTable01.Kind = MyTableGroup.Kind
GROUP BY MyTable01.Val,MyTable01.Kind
ORDER BY Id;

মাই টেবিলের উপর দুটি স্ক্যানের প্রয়োজনের কারণে এটি অন্যান্য উত্তরের তুলনায় অনেক কম দক্ষ হবে।
a_horse_with_no_name

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