লিনকিউ থেকে এসকিউএল - বাম বহিরঙ্গন একাধিক যোগদানের শর্তের সাথে যোগ দিন


148

আমার কাছে নিম্নলিখিত এসকিউএল রয়েছে, যা আমি লিনকিউতে অনুবাদ করার চেষ্টা করছি:

SELECT f.value
FROM period as p 
LEFT OUTER JOIN facts AS f ON p.id = f.periodid AND f.otherid = 17
WHERE p.companyid = 100

আমি বাম বাহ্যিক জোড় (যেমন into x from y in x.DefaultIfEmpty()ইত্যাদি) এর সাধারণ বাস্তবায়ন দেখেছি তবে অন্যান্য যোগদানের শর্তটি কীভাবে প্রবর্তন করতে পারি তা সম্পর্কে নিশ্চিত নই ( AND f.otherid = 17)

সম্পাদনা

AND f.otherid = 17শর্তটি WHOE দানের পরিবর্তে JOIN এর অংশ কেন ? কারণ fকিছু সারির জন্য অস্তিত্ব থাকতে পারে এবং আমি এখনও এই সারিগুলি অন্তর্ভুক্ত করা চাই। শর্তটি জোয়ারের পরে WHERE ধারাতে প্রয়োগ করা হয় - তবে আমি যে আচরণটি চাই তা পাই না।

দুর্ভাগ্যক্রমে এটি:

from p in context.Periods
join f in context.Facts on p.id equals f.periodid into fg
from fgi in fg.DefaultIfEmpty()
where p.companyid == 100 && fgi.otherid == 17
select f.value

এর সমতুল্য বলে মনে হচ্ছে:

SELECT f.value
FROM period as p 
LEFT OUTER JOIN facts AS f ON p.id = f.periodid 
WHERE p.companyid = 100 AND f.otherid = 17

যা আমি পরে করছি ঠিক তা নয়।


খুব সুন্দর! আমি কিছুক্ষণের জন্য এটি সন্ধান করেছি তবে কীভাবে এটি অনুসন্ধান করতে হবে তা নিশ্চিত ছিল না। এই উত্তরে ট্যাগগুলি কীভাবে যুক্ত করবেন তা নিশ্চিত নন। আমি যে সন্ধানের মানদণ্ডটি ব্যবহার করেছি তা এখানে: লিঙ্ক থেকে এসকিএল ফিল্টার যোগ দিতে বা লিনাক থেকে এসকিএল যেখানে ক্লজ যোগ দিতে বা হতে পারে
সলবার্ন

উত্তর:


243

কল করার আগে আপনার যোগদানের শর্তটি চালু করতে হবে DefaultIfEmpty()। আমি কেবল এক্সটেনশন পদ্ধতির বাক্য গঠন ব্যবহার করব:

from p in context.Periods
join f in context.Facts on p.id equals f.periodid into fg
from fgi in fg.Where(f => f.otherid == 17).DefaultIfEmpty()
where p.companyid == 100
select f.value

অথবা আপনি একটি subquery ব্যবহার করতে পারেন:

from p in context.Periods
join f in context.Facts on p.id equals f.periodid into fg
from fgi in (from f in fg
             where f.otherid == 17
             select f).DefaultIfEmpty()
where p.companyid == 100
select f.value

1
ভাগ করে নেওয়ার জন্য ধন্যবাদ। যেখানে থেকে কোয়ালিফায়ার .... ডিফল্টফেমটি স্টেটমেন্ট। আমি জানতাম না যে আপনি এটি করতে পারবেন।
ফ্র্যাঙ্ক থমাস 18

28

এটিও কার্যকর হয় ... ... যদি আপনার একাধিক কলাম যুক্ত হয়

from p in context.Periods
join f in context.Facts 
on new {
    id = p.periodid,
    p.otherid
} equals new {
    f.id,
    f.otherid
} into fg
from fgi in fg.DefaultIfEmpty()
where p.companyid == 100
select f.value

12

আমি জানি এটি " কিছুটা দেরী " তবে কেবল যদি লিনকিউ মেথড সিনট্যাক্সে ( কারন আমি প্রথমে এই পোস্টটি খুঁজে পেয়েছি ) এই কাজ করার প্রয়োজন হয় তবে এটি কীভাবে করা যায় তা:

var results = context.Periods
    .GroupJoin(
        context.Facts,
        period => period.id,
        fk => fk.periodid,
        (period, fact) => fact.Where(f => f.otherid == 17)
                              .Select(fact.Value)
                              .DefaultIfEmpty()
    )
    .Where(period.companyid==100)
    .SelectMany(fact=>fact).ToList();

2
ল্যাম্বডা সংস্করণটি দেখতে খুব দরকারী!
শিখর

2
.Select(fact.Value)হওয়া উচিত.Select(f => f.Value)
পেটর ফেলজম্যান

5

আরও একটি বৈধ বিকল্প হ'ল একাধিক লিনকিউ ক্লজগুলিতে যোগদান করে , নিম্নরূপ:

public static IEnumerable<Announcementboard> GetSiteContent(string pageName, DateTime date)
{
    IEnumerable<Announcementboard> content = null;
    IEnumerable<Announcementboard> addMoreContent = null;
        try
        {
            content = from c in DB.Announcementboards
              // Can be displayed beginning on this date
              where c.Displayondate > date.AddDays(-1)
              // Doesn't Expire or Expires at future date
              && (c.Displaythrudate == null || c.Displaythrudate > date)
              // Content is NOT draft, and IS published
              && c.Isdraft == "N" && c.Publishedon != null
              orderby c.Sortorder ascending, c.Heading ascending
              select c;

            // Get the content specific to page names
            if (!string.IsNullOrEmpty(pageName))
            {
              addMoreContent = from c in content
                  join p in DB.Announceonpages on c.Announcementid equals p.Announcementid
                  join s in DB.Apppagenames on p.Apppagenameid equals s.Apppagenameid
                  where s.Apppageref.ToLower() == pageName.ToLower()
                  select c;
            }

            // Add the specified content using UNION
            content = content.Union(addMoreContent);

            // Exclude the duplicates using DISTINCT
            content = content.Distinct();

            return content;
        }
    catch (MyLovelyException ex)
    {
        // Add your exception handling here
        throw ex;
    }
}

এটি একটি একক লিনক ক্যোয়ারিতে পুরো অপারেশন করার চেয়ে ধীর হবে না?
উমর টি।

@ উমার-টি, হ্যাঁ সম্ভবত, এটি বিবেচনা করে আট বছর আগে আমি যখন এটি লিখেছিলাম। ব্যক্তিগতভাবে আমি সম্পর্কিত উপ-ক্যোয়ারী এখানে Dahlbyk দ্বারা postulated মত stackoverflow.com/a/1123051/212950
MAbraham1

1
একটি "ইউনিয়ন" "ক্রস-জয়েন" এর চেয়ে আলাদা অপারেশন। এটি সংখ্যার তুলনায় বহুগুণ like
সানক্যাট 2000

1
@ সানক্যাট 2000, সংশোধন করার জন্য আপনাকে ধন্যবাদ। শুভ ধন্যবাদ! 👪🦃🙏
এমএব্রাহাম 1

0

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

var result = context.Periods
    .Where(p => p.companyid == 100)
    .GroupJoin(
        context.Facts,
        p => new {p.id, otherid = 17},
        f => new {id = f.periodid, f.otherid},
        (p, f) => new {p, f})
    .SelectMany(
        pf => pf.f.DefaultIfEmpty(),
        (pf, f) => new MyJoinEntity
        {
            Id = pf.p.id,
            Value = f.value,
            // and so on...
        });

-1

আমার কাছে মনে হয় এটি অনুবাদ করার চেষ্টা করার আগে আপনার এসকিউএল কোডটিতে কিছু পুনর্লিখন বিবেচনা করার মূল্য রয়েছে।

ব্যক্তিগতভাবে, আমি ইউনিয়ন হিসাবে এই জাতীয় একটি কোয়েরি লিখতাম (যদিও আমি সম্পূর্ণরূপে নালগুলি এড়াতে পারি!):

SELECT f.value
  FROM period as p JOIN facts AS f ON p.id = f.periodid
WHERE p.companyid = 100
      AND f.otherid = 17
UNION
SELECT NULL AS value
  FROM period as p
WHERE p.companyid = 100
      AND NOT EXISTS ( 
                      SELECT * 
                        FROM facts AS f
                       WHERE p.id = f.periodid
                             AND f.otherid = 17
                     );

সুতরাং আমি অনুমান করি যে আমি @ এমব্রাহাম 1 এর উত্তরের চেতনার সাথে একমত (যদিও তাদের কোড প্রশ্নের সাথে সম্পর্কিত নয় বলে মনে হচ্ছে)।

যাইহোক, দেখে মনে হচ্ছে কোয়েরিটি ডুপ্লিকেট সারি সমন্বয়ে একটি একক কলাম ফলাফল তৈরির জন্য স্পষ্টভাবে তৈরি করা হয়েছে - সত্যই নকল নকল! এই সিদ্ধান্তটি ত্রুটিযুক্ত যে এই সিদ্ধান্তে না আসা কঠিন।

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