কলামের প্রতিটি অনন্য মানের জন্য কেবল প্রথম সারিটি কীভাবে নির্বাচন করবেন


99

ধরা যাক আমার কাছে গ্রাহকের ঠিকানার একটি টেবিল রয়েছে:

CName           |   AddressLine
-------------------------------
John Smith      | 123 Nowheresville
Jane Doe        | 456 Evergreen Terrace
John Smith      | 999 Somewhereelse
Joe Bloggs      | 1 Second Ave

টেবিলে জন স্মিথের মতো একজন গ্রাহকের একাধিক ঠিকানা থাকতে পারে। 'সিএননেমে' নকল রয়েছে সেখানে কেবলমাত্র প্রথম সারিতে ফিরে আসার জন্য আমার এই টেবিলের জন্য নির্বাচিত প্রশ্নটি প্রয়োজন। এই টেবিলের জন্য এটি তৃতীয় (বা 1 ম - এই দুটি ঠিকানাগুলির মধ্যে যে কোনও একটি ঠিক আছে তবে কেবল একটিই ফিরে আসতে পারে) ব্যতীত সমস্ত সারি ফেরত দেওয়া উচিত। সার্ভারটি এর আগেও কলামটির মান আগে দেখেছিল কিনা তার উপর ভিত্তি করে ফিল্টার করতে SELECT ক্যোয়ারিতে আমি কী শব্দ যুক্ত করতে পারি?

উত্তর:


128

খুব সহজ উত্তর যদি আপনি বলেন যে কোন ঠিকানাটি ব্যবহার করা হচ্ছে তা আপনার যত্ন নেই।

SELECT
    CName, MIN(AddressLine)
FROM
    MyTable
GROUP BY
    CName

যদি আপনি সেই অনুযায়ী প্রথমটি চান, বলুন, একটি "সন্নিবেশিত" কলামটি থাকে তবে এটি আলাদা কোয়েরি

SELECT
    M.CName, M.AddressLine,
FROM
    (
    SELECT
        CName, MIN(Inserted) AS First
    FROM
        MyTable
    GROUP BY
        CName
    ) foo
    JOIN
    MyTable M ON foo.CName = M.CName AND foo.First = M.Inserted

যদিও 10 টি কলাম নির্বাচন করার সময় এটি এভাবে ব্যবহার করার উদ্দেশ্যে নয়। এছাড়াও মনে হয় এটি বিট ধরণের কলামটি গ্রহণ করতে পারে না।
nuit9

4
@ ন্যুট 9: অবশ্যই এটি বিট এবং 10 কলামের সাথে কাজ করবে না। এই তথ্যগুলির কোনওটিই আপনার প্রশ্নে নেই। আপনি ২ য় কৌশল বা বেন থুলের কৌশলটি ব্যবহার করবেন। আপনি কীভাবে বিশেষভাবে জিজ্ঞাসা করেছিলেন তার উত্তর দিয়েছি, কীভাবে আরও সাধারণভাবে সমাধান করা যায় তার পয়েন্টার সহ।
জিবিএন

প্রথম অংশটি একাধিক কলামের সাথে কাজ করে, যদিও বিট-টাইপ কলামগুলির সাথে নয়। যদিও এমএস এসকিউএল সার্ভারে এটি পরীক্ষা করেছি ২০১ 2016 সালে।
নেটফিড

27

এসকিউএল 2 কে 5 + তে আপনি এর মতো কিছু করতে পারেন:

;with cte as (
  select CName, AddressLine,
  rank() over (partition by CName order by AddressLine) as [r]
  from MyTable
)
select CName, AddressLine
from cte
where [r] = 1

7
অনুগ্রহ করে র‌্যাঙ্ক, বিভাজন এবং [আর] কি করবে
রবার্তো

10

আপনি row_number()সারিটির সারি নম্বর পেতে ব্যবহার করতে পারেন । এটি overকমান্ডটি ব্যবহার করে - partition byধারাটি কখন নম্বরটি পুনরায় আরম্ভ করতে হবে এবং order byসারি সংখ্যাটি কী অর্ডার করতে হবে তা নির্বাচন করে। এমনকি যদি আপনি order byআপনার ক্যোয়ারির শেষে একটি যোগ করেছেন , এটি overনম্বর দেওয়ার সময় কমান্ডের ক্রম সংরক্ষণ করবে ।

select *
from mytable
where row_number() over(partition by Name order by AddressLine) = 1


4
এটি এমএস-এসকিউএল-এর জন্যও অনুমোদিত নয়।
মিক্স্সিফয়েড

4
ROW_NUMBER()Whereটেরাদাতায় পাশাপাশি ধারাতেও কাজ করে না
পাইরেট এক্স

6

আপনি row_numer() over(partition by ...)সিনট্যাক্সটি এর মতো ব্যবহার করতে পারেন :

select * from
(
select *
, ROW_NUMBER() OVER(PARTITION BY CName ORDER BY AddressLine) AS row
from myTable
) as a
where row = 1

এটি যা করে তা হ'ল এটি একটি কলাম তৈরি করে row, যা এমন একটি পাল্টা হয় যা প্রতিবার একই দেখায় বৃদ্ধি পায় CNameএবং সেই ঘটনাগুলি সূচক করে AddressLine। চাপিয়ে দিয়ে where row = 1, CNameযার AddressLineবর্ণমালায় প্রথম আসবে তা নির্বাচন করতে পারে । তাহলে order byছিল desc, তাহলে এটি বাছাই করবে CNameযার AddressLineগত বর্ণানুক্রমে আসে।


1

এটি আপনাকে প্রতিটি সদৃশ সারির একটি সারি দেবে। এটি আপনাকে বিট-টাইপ কলামগুলিও দেবে এবং এটি কমপক্ষে এমএস স্কেল সার্ভারে কাজ করে।

(select cname, address 
from (
  select cname,address, rn=row_number() over (partition by cname order by cname) 
  from customeraddresses  
) x 
where rn = 1) order by cname

পরিবর্তে আপনি যদি সমস্ত সদৃশ সন্ধান করতে চান তবে rn = 1 কে rn> পরিবর্তন করুন। আশা করি এটি সাহায্য করবে

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