লিনকুই - বাম যোগদান, গ্রুপ অনুসারে এবং গণনা করুন


166

ধরা যাক আমার কাছে এই এসকিউএল রয়েছে:

SELECT p.ParentId, COUNT(c.ChildId)
FROM ParentTable p
  LEFT OUTER JOIN ChildTable c ON p.ParentId = c.ChildParentId
GROUP BY p.ParentId

আমি কীভাবে এটিকে এসকিউএল-তে লিনকিউতে অনুবাদ করতে পারি? আমি COUNT (c.ChildId) এ আটকে গেলাম, উত্পন্ন এসকিউএল সবসময় COUNT (*) আউটপুট করে। আমি এ পর্যন্ত যা পেয়েছি তা এখানে:

from p in context.ParentTable
join c in context.ChildTable on p.ParentId equals c.ChildParentId into j1
from j2 in j1.DefaultIfEmpty()
group j2 by p.ParentId into grouped
select new { ParentId = grouped.Key, Count = grouped.Count() }

ধন্যবাদ!

উত্তর:


189
from p in context.ParentTable
join c in context.ChildTable on p.ParentId equals c.ChildParentId into j1
from j2 in j1.DefaultIfEmpty()
group j2 by p.ParentId into grouped
select new { ParentId = grouped.Key, Count = grouped.Count(t=>t.ChildId != null) }

ঠিক আছে, যে কাজ করে, কিন্তু কেন? এর মাধ্যমে কীভাবে ভাবছেন? নাল মান গণনা কীভাবে আমাদের COUNT (সি। চিল্ডআইডি) হিসাবে একইভাবে দেয় না? ধন্যবাদ।
pbz

4
এসকিউএল এইভাবে কাজ করে। COUNT (ক্ষেত্রের নাম) সেই ক্ষেত্রের সারিগুলি গণনা করবে যা শূন্য নয়। হয়তো আমি আপনার প্রশ্নটি পাই না, দয়া করে স্পষ্ট করে বলুন যদি এটি হয় তবে।
মেহরদাদ আফশারি

আমার ধারণা আমি সারিগুলি গণনা করার ক্ষেত্রে সর্বদা এটি সম্পর্কে ভেবেছিলাম তবে আপনি সঠিক, কেবল নন-নাল মান গণনা করা হয়। ধন্যবাদ।
পিবিজেড

1
.কাউন্ট () COUNT (*) উত্পন্ন করবে যা সেই গোষ্ঠীর সমস্ত সারি গণনা করবে the
মেহরদাদ আফশারি

T => t.ChildID এর তুলনা করে আমার ঠিক একই সমস্যা হয়েছিল! = নাল আমার পক্ষে কাজ করে নি। ফলাফল সর্বদা একটি নাল বস্তু ছিল এবং রিশার্পার অভিযোগ করেছিলেন যে অভিব্যক্তিটি সর্বদা সত্য। সুতরাং আমি (t => t! = নাল) ব্যবহার করেছি এবং এটি আমার পক্ষে কাজ করেছে।
জো

55

একটি subquery ব্যবহার বিবেচনা করুন:

from p in context.ParentTable 
let cCount =
(
  from c in context.ChildTable
  where p.ParentId == c.ChildParentId
  select c
).Count()
select new { ParentId = p.Key, Count = cCount } ;

যদি ক্যোয়ারির প্রকারগুলি কোনও সমিতি দ্বারা সংযুক্ত থাকে, তবে এটি এতে সরল করে:

from p in context.ParentTable 
let cCount = p.Children.Count()
select new { ParentId = p.Key, Count = cCount } ;

যদি আমি সঠিকভাবে মনে রাখি (কিছুক্ষণ হয়ে গেছে), সেই ক্যোয়ারীটি একটি বৃহতটির একটি সরলিকৃত সংস্করণ ছিল। আমার যা যা প্রয়োজন তা হ'ল যদি আপনার সমাধানটি পরিষ্কার করা যায় তবে আরও ভাল / ভাল হত।
pbz

1
আপনার মন্তব্যটি আসল প্রশ্ন এবং উত্তোলিত উত্তরগুলির সাথে প্রসঙ্গে বোঝায় না। অতিরিক্ত হিসাবে - আপনি যদি চাবিটির চেয়ে আরও বেশি কিছু চান তবে আপনার কাছে পুরো প্যারেন্ট সারিটি আঁকতে হবে।
অ্যামি বি

letকীওয়ার্ড সহ সমাধানটি @ মশ গ্রুপের সাথে যুক্ত সমাধানের মতো একটি সাবকিউরি তৈরি করবে।
মোহসেন আফশিন

@ মোহেনআফশিন হ্যাঁ, এটি সরাসরি উপরে আমার উত্তরটিতে সাবকিউয়ের সাথে ক্যোয়ারির মতো একটি সাবকিউরি তৈরি করে।
অ্যামি বি

39

বিলম্বিত উত্তর:

আপনার সমস্ত কাজ গণনা () করে থাকলে আপনার মোটামুটি বাম যোগদানের প্রয়োজন হবে না । নোটটি join...intoআসলে অনুবাদ করা হয়েছে GroupJoinযার মধ্যে new{parent,IEnumerable<child>}এমন গ্রুপিংগুলি ফিরে আসে যাতে আপনাকে কেবল Count()গ্রুপে কল করতে হবে :

from p in context.ParentTable
join c in context.ChildTable on p.ParentId equals c.ChildParentId into g
select new { ParentId = p.Id, Count = g.Count() }

এক্সটেনশন দিয়ে পদ্ধতি সিনট্যাক্স একটি join intoসমতূল্য GroupJoin(যখন একটি joinএকটি ছাড়া intoহয় Join):

context.ParentTable
    .GroupJoin(
                   inner: context.ChildTable
        outerKeySelector: parent => parent.ParentId,
        innerKeySelector: child => child.ParentId,
          resultSelector: (parent, children) => new { parent.Id, Count = children.Count() }
    );

8

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

এখানে আমার সমাধান:

from p in context.ParentTable
join c in context.ChildTable on p.ParentId equals c.ChildParentId into joined
select new { ParentId = p.ParentId, Count = joined.Count() }

ভিন্ন বেশিরভাগই এখানে সমাধান ভোট দিয়েছেন, আমাদের দরকার নেই J1 , j2 এবং নাল পরীক্ষণ কাউন্ট (টি => t.ChildId! = নাল)


7
 (from p in context.ParentTable     
  join c in context.ChildTable 
    on p.ParentId equals c.ChildParentId into j1 
  from j2 in j1.DefaultIfEmpty() 
     select new { 
          ParentId = p.ParentId,
         ChildId = j2==null? 0 : 1 
      })
   .GroupBy(o=>o.ParentId) 
   .Select(o=>new { ParentId = o.key, Count = o.Sum(p=>p.ChildId) })
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.