লারাভেলের নন-কী কলাম ক্ষেত্রের জন্য আলাদা মান কীভাবে পাবেন?


94

এটি বেশ সহজ হতে পারে তবে কীভাবে করবেন তার কোনও ধারণা নেই।

আমার কাছে একটি টেবিল রয়েছে যা নির্দিষ্ট নন-কী কলাম ক্ষেত্রের জন্য বারবার মান থাকতে পারে। কোয়েরি বিল্ডার বা এলওলিউড ব্যবহার করে কীভাবে আমি এসকিউএল কোয়েরি লিখব যা এই কলামটির জন্য স্বতন্ত্র মানগুলি সহ সারি পেতে পারে?

মনে রাখবেন যে আমি কেবল সেই কলামটিই আনছি না, এটি অন্যান্য কলামের মানগুলির সাথে মিলিত, তাই distinct()সম্ভবত এটি কাজ করতে পারে না। সুতরাং এই প্রশ্নটি মূলত এমন কীভাবে হতে পারে যে কলামটি আমি কীভাবে distinct()কোনও প্যারামিটারগুলি গ্রহণ না করে এখন কোনও প্রশ্নের সাথে আলাদা হতে চাই ?

উত্তর:


115

আপনার ব্যবহার করা উচিত groupby। ক্যোয়ারী বিল্ডারে আপনি এইভাবে এটি করতে পারেন:

$users = DB::table('users')
            ->select('id','name', 'email')
            ->groupBy('name')
            ->get();

4
আমার কাছে একটি টেবিল "বার্তা" রয়েছে (একটি চ্যাটের জন্য ব্যবহৃত) এবং আমি সর্বশেষ বার্তাটি পেতে চাই যা প্রত্যয়িত ব্যবহারকারী প্রতিটি কথোপকথন থেকে পেয়েছেন। গ্রুপবাইয়ের সাহায্যে আমি কেবল একটি বার্তা পেতে পারি তবে আমি প্রথমটি পাই এবং আমার শেষ বার্তাটি দরকার। দেখে মনে হচ্ছে অর্ডারটি কাজ করে না।
জে কার্লোসআর

10
আপনি যদি কোনও গণিত ক্রিয়াকলাপ যেমন SUM, AVG, MAX ইত্যাদির প্রয়োগ করতে চান না তবে "গ্রুপ বাই" সঠিক উত্তর নয় (আপনি এটি ব্যবহার করতে পারেন, তবে আপনার এটি ব্যবহার করা উচিত নয়)। আপনার স্বতন্ত্র ব্যবহার করা উচিত। মাইএসকিউএল এ আপনি একটি কলামের জন্য DISTINCT ব্যবহার করতে পারেন এবং ফলাফল সেটটিতে আরও কলাম যুক্ত করতে পারেন: "ব্যবহারকারীদের কাছ থেকে নাম, আইডি, ইমেল নির্বাচন করুন"। স্বতঃস্ফূর্ততার সাথে আপনি এটি> এটি-> নির্বাচন করে (['নাম', 'আইডি', 'ইমেল']) -> স্বতন্ত্র () -> পান ();
সেরগি

4
আমি যখন where()এটি যুক্ত করি তখন এটি কীভাবে সংশোধন করতে পারি?
tq

4
আমি যখন এটি ব্যবহার করি তখন এটি 'আইডি' এবং 'ইমেল' দেখায় গ্রুপপাইয়ের মধ্যে নেই () আমাকে গ্রুপবাই ('আইডি', 'নাম', 'ইমেল') ব্যবহার করা দরকার। যা কার্যকর নয়।
হক

4
কিছু খেয়াল করুন: group byযেমনটি হয় না distinct। এসকিউএল কোয়েরির group byমতো সামগ্রিক ফাংশনের আচরণ পরিবর্তন করবে count()distinctএই জাতীয় ফাংশনগুলির আচরণ পরিবর্তন করবে না, সুতরাং আপনি কোনটি ব্যবহার করবেন তার উপর নির্ভর করে আপনি বিভিন্ন ফলাফল পান get
স্কিটিস

77

স্বতঃস্ফূর্তভাবে আপনি এই জাতীয় প্রশ্নও করতে পারেন:

$users = User::select('name')->distinct()->get();


12
প্রশ্নটি বিশেষভাবে জিজ্ঞাসা করেNote that I am not fetching that column only, it is in conjunction with other column values
হিরনহ্যামস্টার

12
@ হিরনহ্যামস্টার: ওকেই। যাইহোক, এই উত্তর এখনো অতিক্রম অন্যদের জন্য দরকারী ...
Pathros

4
আমার পক্ষে কার্যকর নয়, আমি বিশেষত ওপিটি কী তা লক্ষ্য করছি। এটি কোনও সহজ অনুসন্ধান নয়।
ব্লেম

4
$users = User::select('column1', 'column2', 'column3')->distinct()->get();
মার্ক হিরো

এছাড়াও আপনি ->orderBy('name')যদি এটির সাথে এটি ব্যবহার করতে চান তবে আপনারও প্রয়োজন chunk
চিবুয়েজ ওপাটা

26

স্পষ্টত আপনি এটি ব্যবহার করতে পারেন

$users = User::select('name')->groupBy('name')->get()->toArray() ;

গ্রুপবাই প্রকৃতপক্ষে স্বতন্ত্র মানগুলি আনছে, প্রকৃতপক্ষে গ্রুপবাই একই মানগুলিকে শ্রেণিবদ্ধ করবে, যাতে আমরা তাদের উপর সামগ্রিক ফাংশন ব্যবহার করতে পারি। তবে এই দৃশ্যে আমাদের কোনও সামগ্রিক ফাংশন নেই, আমরা কেবলমাত্র সেই মানটি নির্বাচন করছি যা ফলাফলের স্বতন্ত্র মানগুলির কারণ হতে পারে


4
কিভাবে কাজ করে? গ্রুপপাই আসলে কী স্বতন্ত্র ব্যবহারকারীর নাম আনছে? আপনি দয়া করে আরও কিছুটা ব্যাখ্যা করতে পারেন কীভাবে এই উত্তরটির সমস্যার উত্তর দেয়?
ফলিক্স গাগনন-গ্রেনিয়ার

হ্যাঁ গ্রুপবাই আসলে স্বতন্ত্র মানগুলি আনছে, প্রকৃতপক্ষে গ্রুপবাই একই মানগুলিকে শ্রেণিবদ্ধ করবে, যাতে আমরা তাদের উপর সামগ্রিক ফাংশন ব্যবহার করতে পারি। তবে এই দৃশ্যে আমাদের কোনও সামগ্রিক ফাংশন নেই, আমরা কেবলমাত্র সেই মানটি নির্বাচন করছি যা ফলাফলের স্বতন্ত্র মানগুলির কারণ ঘটবে।
সালার

আমি দেখছি .. তাহলে, এই উত্তরটি কীভাবে মার্সিনের উত্তর থেকে আলাদা? একটি পৃথক উত্তর থাকা ঠিক আছে, যতক্ষণ আপনি এটি কীভাবে আলাদা তা ব্যাখ্যা করতে পারেন এবং এটি কী ত্রুটি সমাধান করে :) মন্তব্যে উত্তর দেওয়ার জন্য বিরক্ত করবেন না, দয়া করে আপনার প্রশ্নটি সরাসরি প্রাসঙ্গিক তথ্যের সাথে সম্পাদনা করুন।
ফলিক্স গাগনন-গ্রেনিয়ার

4
ফলাফল একই, এটি আপনার প্রকল্পের উপর নির্ভর করে ওআরএম ব্যবহার করতে বা কোয়েরি বিল্ডার ব্যবহার করতে, যদি আপনি তাদের মধ্যে একটি ব্যবহার করে থাকেন তবে তার সাথে স্থির থাকা আরও ভাল। সে কারণেই আমি আপনার প্রশ্নের উত্তর অন্যভাবে দিয়েছি।
সালার

ঠিক আছে, আমার এই সমস্যাটি রয়েছে যেখানে আপনি এখন যদি কোনও আইটেমটি in_array()ফাংশনটি ব্যবহার করে বিদ্যমান কিনা তা পরীক্ষা করতে চান তবে এটি কখনই কাজ করে না। এটি ঠিক করার জন্য, আমি ->lists()পরিবর্তে চেষ্টা করেছি (সংস্করণ 5.2)। সুতরাং, $users = User::select('name')->groupBy('name')->lists('name');পিএইচপি এর জন্য ভাল কাজ করেছেন in_array();
পাঠরোস

19

যদিও আমি এর উত্তর দিতে দেরি করছি, এলওলিউড ব্যবহার করে স্বতন্ত্র রেকর্ড পাওয়ার আরও ভাল পদ্ধতির উপায় হবে

$user_names = User::distinct()->get(['name']);

ঠিক আছে, আপনি আমাদের দেখিয়ে মূল্য যোগ করেছেন যে কেউ get()পদ্ধতিতে ক্ষেত্রের নামগুলিরও পরম পাস করতে পারে (এবং আমি পদ্ধতিটিতেও পরীক্ষা করেছি first()), যা select()এখানে কয়েকটি উত্তরে বর্ণিত পদ্ধতিটি ব্যবহারের সমতুল্য । যদিও groupByএখনও কোনওরকমে সর্বোচ্চ স্কোর বলে মনে হচ্ছে। তবে এটি সত্যই স্বতন্ত্র হবে যদি আমি কেবলমাত্র কলামটিই নির্বাচন করছি।
gthuo

পারফরম্যান্সের ভিত্তিতে, স্বতন্ত্রভাবে গ্রুপবাইয়ের স্কোর করতে চলেছে, কারণ এসকিউএল ইঞ্জিনে রেকর্ডগুলি প্রথমে নির্বাচিত হবে গ্রুপের তুলনায় ইঞ্জিন প্রথমে সমস্ত রেকর্ড নির্বাচন করবে এবং তারপরে গ্রুপের দ্বারা ..
রশখলে

4
$user_names = User::distinct()->count(['name']);এছাড়াও কাজ করে
বীরা

11

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

$users = DB::table('users')
        ->select('id','name', 'email')
        ->get();

foreach($users->unique('name') as $user){
  //....
}

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

     $users = DB::table('users')
        ->select('id','name', 'email')
        ->get()
        ->keyBy('name');

কীবি আপনাকে আরও জটিল জিনিসের জন্য কল ব্যাক ফাংশন যুক্ত করার অনুমতি দেয় ...

     $users = DB::table('users')
        ->select('id','name', 'email')
        ->get()
        ->keyBy(function($user){
              return $user->name . '-' . $user->id;
         });

যদি আপনার বড় সংগ্রহগুলি নিয়ে পুনরাবৃত্তি করতে হয় তবে এতে একটি কী যুক্ত করে পারফরম্যান্স সমস্যার সমাধান করুন।


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

আপনার একটি ভাল পয়েন্ট আছে। এই সংগ্রহটি বৃহত সংগ্রহের ক্ষেত্রে দুর্দান্ত পারফরম্যান্সের ভিত্তিতে নাও হতে পারে এবং এটি পৃষ্ঠা-রচনার জন্য কাজ করবে না। আমি মনে করি আমার কাছে যা আছে তার থেকে আরও ভাল উত্তর আছে।
জেড লিঞ্চ

6

নোট করুন যে groupByউপরে ব্যবহৃত হিসাবে পোস্টগ্রাজের জন্য কাজ করবে না।

ব্যবহার distinctকরা সম্ভবত একটি ভাল বিকল্প - যেমন $users = User::query()->distinct()->get();

আপনি যদি ব্যবহার queryকরেন তবে অনুরোধ অনুযায়ী সমস্ত কলাম নির্বাচন করতে পারেন।


6

**

লারাভেল 5.8 এর জন্য পরীক্ষিত

**

যেহেতু আপনি টেবিল থেকে সমস্ত কলাম পেতে চান, তাই আপনি সমস্ত ডেটা সংগ্রহ করতে পারেন এবং তারপরে এটি অনন্য নামে পরিচিত সংগ্রহ ফাংশনটি ব্যবহার করে ফিল্টার করতে পারেন

// Get all users with unique name
User::all()->unique('name')

বা

// Get all & latest users with unique name 
User::latest()->get()->unique('name')

আরও তথ্যের জন্য আপনি লারাভেল সংগ্রহ ডকুমেন্টেশন চেক করতে পারেন

সম্পাদনা করুন: ইউনিক () ব্যবহার করে আপনি প্রথমে ব্যবহারকারীর টেবিল থেকে সমস্ত ডেটা পাবেন এবং তারপরে লারাভেল এটি ফিল্টার করবে পারফোনেন্স নিয়ে সমস্যা হতে পারে। আপনার কাছে প্রচুর ব্যবহারকারীর ডেটা থাকলে এই উপায়টি ভাল নয়। আপনি কোয়েরি বিল্ডার ব্যবহার করতে পারেন এবং প্রতিটি ক্ষেত্রকে কল করতে পারেন যা আপনি ব্যবহার করতে চান উদাহরণস্বরূপ:

User::select('username','email','name')->distinct('name')->get();

আপনি ডিবি থেকে প্রথমে সমস্ত ডেটা পাওয়ার পরে এটি কার্যকর নয়
রেজার মুরাইথি

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

5

$users = User::select('column1', 'column2', 'column3')->distinct()->get();সারণীতে স্বতন্ত্র সারিগুলির জন্য সমস্ত তিনটি সংঘটন পুনরুদ্ধার করে। আপনি নিজের ইচ্ছেমতো কলাম যুক্ত করতে পারেন।


3

আমি অনন্য মূল্যবোধের সমতল অ্যারে উত্পাদন করতে এই পদ্ধতিটি বেশ ভালভাবে (আমার জন্য) কাজ করে দেখলাম:

$uniqueNames = User::select('name')->distinct()->pluck('name')->toArray();

আপনি যদি ->toSql()এই কোয়েরি বিল্ডারে দৌড়ে থাকেন তবে আপনি দেখতে পাবেন যে এটি এর মতো একটি কোয়েরি উত্পন্ন করে:

select distinct `name` from `users`

->pluck()জ্বালান \ সংগ্রহে Majuro (SQL কোয়েরি মাধ্যমে নয়) দ্বারা পরিচালিত হয়।


1

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

Message::where('from_user', $user->id)
        ->select(['from_user', 'to_user'])
        ->selectRaw('MAX(created_at) AS last_date')
        ->groupBy(['from_user', 'to_user'])
        ->orderBy('last_date', 'DESC')
        ->get()


0

যারা আমাকে পছন্দ করেন তারাও একই ভুল করছেন। লারাভেল ৫.7-এ পরীক্ষিত বিস্তৃত উত্তর এখানে

উ: ডিবি রেকর্ডস

ইউজারফাইলে :: অর্ডারবাই ('made_at', 'desc') -> get () -> toArray ();

Array
(
    [0] => Array
        (
            [id] => 2073
            [type] => 'DL'
            [url] => 'https://i.picsum.photos/12/884/200/300.jpg'
            [created_at] => 2020-08-05 17:16:48
            [updated_at] => 2020-08-06 18:08:38
        )

    [1] => Array
        (
            [id] => 2074
            [type] => 'PROFILE'
            [url] => 'https://i.picsum.photos/13/884/200/300.jpg'
            [created_at] => 2020-08-05 17:20:06
            [updated_at] => 2020-08-06 18:08:38
        )

    [2] => Array
        (
            [id] => 2076
            [type] => 'PROFILE'
            [url] => 'https://i.picsum.photos/13/884/200/300.jpg'
            [created_at] => 2020-08-05 17:22:01
            [updated_at] => 2020-08-06 18:08:38
        )

    [3] => Array
        (
            [id] => 2086
            [type] => 'PROFILE'
            [url] => 'https://i.picsum.photos/13/884/200/300.jpg'
            [created_at] => 2020-08-05 19:22:41
            [updated_at] => 2020-08-06 18:08:38
        )
)

বি পছন্দসই দলবদ্ধ ফলাফল

ইউজারফিল :: নির্বাচন করুন ('টাইপ', 'ইউআরএল', 'আপডেটড্যাট) -> স্বতন্ত্র (' টাইপ ') -> পান () -> টু অ্যারে ();

Array
(
    [0] => Array
        (
            [type] => 'DL'
            [url] => 'https://i.picsum.photos/12/884/200/300.jpg'
            [updated_at] => 2020-08-06 18:08:38 
        )

    [1] => Array
        (
            [type] => 'PROFILE'
            [url] => 'https://i.picsum.photos/13/884/200/300.jpg'
            [updated_at] => 2020-08-06 18:08:38
        )
)

সুতরাং শুধুমাত্র সেই কলামগুলিতে পাস করুন "select()"যার মান একই of উদাহরণস্বরূপ: 'type','url'। আপনি আরও কলাম যুক্ত করতে পারেন যদি তাদের মান একই থাকে 'updated_at'

আপনি যদি পাস "created_at"বা প্রবেশের চেষ্টা "id"করেন "select()", তবে আপনি এ হিসাবে রেকর্ডগুলি পাবেন তবে ডিবিতে প্রতিটি সারির জন্য এগুলি পৃথক।


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