লিংক থেকে এসকিউএল বাম বহিরাগত যোগদান


140

এই কোয়েরিটি কি LEFT OUTERযোগ দেওয়ার সমতুল্য ?

//assuming that I have a parameter named 'invoiceId' of type int
from c in SupportCases
let invoice = c.Invoices.FirstOrDefault(i=> i.Id == invoiceId)
where (invoiceId == 0 || invoice != null)    
select new 
{
      Id = c.Id
      , InvoiceId = invoice == null ? 0 : invoice.Id
}

উত্তর:


167

পুরোপুরি নয় - যেহেতু বাম-বাহ্যিক জোড়ের প্রতিটি "বাম" সারি 0-n "ডান" সারিগুলির সাথে মিলবে (দ্বিতীয় সারণীতে), যেখানে আপনার সাথে মিলছে কেবল 0-1। বাম বাহ্যিক যোগদানের জন্য আপনার প্রয়োজন SelectManyএবং DefaultIfEmptyউদাহরণস্বরূপ:

var query = from c in db.Customers
            join o in db.Orders
               on c.CustomerID equals o.CustomerID into sr
            from x in sr.DefaultIfEmpty()
            select new {
               CustomerID = c.CustomerID, ContactName = c.ContactName,
               OrderID = x == null ? -1 : x.OrderID };   

( বা এক্সটেনশন পদ্ধতিগুলির মাধ্যমে )


19
এই পাগল সিনট্যাক্স কীভাবে কাজ করে কেউ ব্যাখ্যা করতে পারে? এই কীওয়ার্ডগুলির যেকোনটি কীভাবে যাদুকরীভাবে এটিকে বামে যুক্ত করে তোলে তা আমি দেখতে ব্যর্থ। "ইন এসআর" কী করে? লিনাক মাঝে মাঝে আমাকে হতাশ করে :)
জো ফিলিপস

2
@ জোফিলিপস আমার কাছে প্রচুর এসকিউএল অভিজ্ঞতা রয়েছে তবে লিনকিউ শিখার চেষ্টা করা কাদা দিয়ে মোড় নেওয়ার মতো। আমি একমত, এটা একেবারে পাগল।
নিক.এমসিডার্মাইড

: @ Marc-gravell তুমি কি আমাকে linq রূপান্তর আমার SQL কোয়েরি সমাধানে সাহায্য করতে পারে stackoverflow.com/questions/28367941/...
বিশাল আমি পাতিল

@ বিশিষ্ঠাপতিল কেন আপনি এসকিউএল থেকে লিনকুতে রূপান্তর করতে চান? এসকিউএল ঠিকঠাক কাজ করে এবং আরও বেশি অনুমানযোগ্য এবং দক্ষ ...
মার্ক গ্র্যাভেল

1
@ বিষালিপাতিল তাই ... কেন? প্রায় প্রতিটি লিনকিউ সরঞ্জামের মধ্যে হাতে লিখিত এসকিউএল চালনার ক্ষমতা অন্তর্ভুক্ত থাকে। কেন শুধু তাই না?
মার্ক Gravell

216

আপনার বিবৃতিতে প্রয়োজন নেই:

var query = 
    from customer in dc.Customers
    from order in dc.Orders
         .Where(o => customer.CustomerId == o.CustomerId)
         .DefaultIfEmpty()
    select new { Customer = customer, Order = order } 
    //Order will be null if the left join is null

এবং হ্যাঁ, উপরের ক্যোয়ারীটি সত্যই একটি বাম আউটরের যোগদান তৈরি করে।

একই রকম প্রশ্নের লিঙ্ক যা একাধিক বাম যোগ দেয়: লিঙ্ক থেকে স্ক্যুয়াল: একাধিক বাম বাহ্যিক যোগদান করে


14
যদিও আমি জানি যে @ মার্ক গ্রাভভেলের উত্তরটি কাজ করে, আমি সত্যিই এই পদ্ধতিটিকে পছন্দ করি কারণ আইএমও এটি বাম জোড়ের মতো হওয়া উচিত এর সাথে সামঞ্জস্যপূর্ণ feels
llaughlin

1
দুর্দান্ত উত্তর। গুগল অনুসন্ধানের 5 ঘন্টারও বেশি সময় অনুসন্ধান করা। এটিই কেবলমাত্র এসকিউএল এর সাথে যুক্ত হতে থাকবে।
ফয়সাল এমকিউ

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

2
@ জিম ধন্যবাদ :-) আমি খুশি যে এই উত্তর থেকে এখনও ডেভেলস মাইলেজ পাচ্ছে। আমি সম্পূর্ণরূপে সম্মত হই যে ডিফল্টআইফেম্পটি () স্টেটমেন্টগুলিতে ব্যবহারের চেয়ে অনেক বেশি প্রাকৃতিক অনুভব করে।
আমির

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

13
Public Sub LinqToSqlJoin07()
Dim q = From e In db.Employees _
        Group Join o In db.Orders On e Equals o.Employee Into ords = Group _
        From o In ords.DefaultIfEmpty _
        Select New With {e.FirstName, e.LastName, .Order = o}

ObjectDumper.Write(q) End Sub

চেক http://msdn.microsoft.com/en-us/vbasic/bb737929.aspx


দুর্দান্ত চেষ্টা করুন তবে দেখে মনে হচ্ছে ওপি সি # ব্যবহার করছে। ভিবি সিনট্যাক্স অদ্ভুতভাবে পৃথক।
লেভিটিকন

5

আমি 1 সমাধান পেয়েছি। যদি এই জাতীয় এসকিউএল (বাম যোগদান) লিঙ্ক সত্তায় অনুবাদ করতে চান ...

এসকিউএল:

SELECT * FROM [JOBBOOKING] AS [t0]
LEFT OUTER JOIN [REFTABLE] AS [t1] ON ([t0].[trxtype] = [t1].[code])
                                  AND ([t1]. [reftype] = "TRX")

LINQ:

from job in JOBBOOKINGs
join r in (from r1 in REFTABLEs where r1.Reftype=="TRX" select r1) 
          on job.Trxtype equals r.Code into join1
from j in join1.DefaultIfEmpty()
select new
{
   //cols...
}

এই মন্তব্যটি দেখুন , লিনাক-টু-এসকিউএল সত্তারা সমর্থন করে না DefaultIfEmpty
টিজে ক্রাউডার

2

আমি আরও একটি জিনিস যোগ করতে চাই। লিনকু থেকে এসকিউএল-তে যদি আপনার ডিবিটি সঠিকভাবে নির্মিত হয় এবং আপনার টেবিলগুলি বিদেশী কী বাধার মধ্য দিয়ে সম্পর্কিত হয়, তবে আপনাকে কোনও যোগ দেওয়ার দরকার নেই।

লিনকুইপ্যাড ব্যবহার করে আমি নিম্নলিখিত লিনকিউ কোয়েরি তৈরি করেছি:

//Querying from both the CustomerInfo table and OrderInfo table
from cust in CustomerInfo
where cust.CustomerID == 123456
select new {cust, cust.OrderInfo}

যা নীচে (কিছুটা কাটা) ক্যোয়ারিতে অনুবাদ করা হয়েছিল

 -- Region Parameters
 DECLARE @p0 Int = 123456
-- EndRegion
SELECT [t0].[CustomerID], [t0].[AlternateCustomerID],  [t1].[OrderID], [t1].[OnlineOrderID], (
    SELECT COUNT(*)
    FROM [OrderInfo] AS [t2]
    WHERE [t2].[CustomerID] = [t0].[CustomerID]
    ) AS [value]
FROM [CustomerInfo] AS [t0]
LEFT OUTER JOIN [OrderInfo] AS [t1] ON [t1].[CustomerID] = [t0].[CustomerID]
WHERE [t0].[CustomerID] = @p0
ORDER BY [t0].[CustomerID], [t1].[OrderID]

LEFT OUTER JOINউপরের দিকে খেয়াল করুন।


1

কর্মক্ষমতা যত্ন নিন:

আমি অভিজ্ঞতা পেয়েছি যে কমপক্ষে EF কোরের সাথে এখানে দেওয়া বিভিন্ন উত্তরগুলির ফলে বিভিন্ন পারফরম্যান্স হতে পারে। আমি অবগত যে ওপি লিনককে এসকিউএল সম্পর্কে জিজ্ঞাসা করেছিল, তবে আমার কাছে মনে হয় যে একই প্রশ্নগুলি ইএফ কোর সম্পর্কেও ঘটে occur

একটি নির্দিষ্ট ক্ষেত্রে আমাকে হ্যান্ডেল করতে হয়েছিল, মার্ক গ্রাভেলের পরামর্শ অনুসারে (সিন্ট্যাক্টিক্যালি ভাল) একটি ক্রসের অভ্যন্তরে বাম সাথে যোগ দেয় - মাইক ইউ বর্ণিত অনুরূপ - যার ফলাফল ছিল যে এই নির্দিষ্ট প্রশ্নের জন্য আনুমানিক ব্যয় দুটি ছিল কোনও ক্রসের সাথে যোগ না হওয়া কোনও প্রশ্নের তুলনায় উচ্চতর বার । সার্ভারের প্রয়োগের সময় 3 এর গুণক দ্বারা পৃথক হয় । [1]

মার্ক গ্রাভেলের সমাধানের ফলে ক্রস যোগ না দিয়ে একটি ক্যোয়ারী তৈরি হয়েছিল।

প্রসঙ্গ: আমার মূলত দুটি টেবিলের উপর দুটি বাম সংযুক্তি সম্পাদন করা দরকার যার প্রত্যেকটিতে আবার অন্য টেবিলে যোগদানের প্রয়োজন। তদুপরি, সেখানে আমার যে টেবিলগুলির উপর আমার বাম জোড় প্রয়োগ করতে হবে তার উপর অন্যান্য কোথায়-শর্তগুলি নির্দিষ্ট করতে হয়েছিল। এছাড়াও, প্রধান টেবিলে আমার দুটি অভ্যন্তরীণ যোগদান হয়েছিল।

আনুমানিক অপারেটর খরচ:

  • ক্রস প্রয়োগ সহ: 0.2534
  • ক্রস ছাড়াই প্রয়োগ করুন: 0.0991।

এমএসে সার্ভারের প্রয়োগের সময় (ক্যুরিগুলি 10 বার কার্যকর করা হয়; সেট সংখ্যার সময় ব্যবহারের মাধ্যমে পরিমাপ করা হয়):

  • ক্রস প্রয়োগ সহ: 5, 6, 6, 6, 6, 6, 6, 6, 6, 6
  • ক্রস ছাড়াই প্রয়োগ করুন: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2

(উভয় প্রশ্নের জন্য খুব প্রথম রানটি ধীর ছিল; মনে হচ্ছে কিছু ক্যাশে হয়েছে))

টেবিলের আকার:

  • প্রধান টেবিল: 87 সারি,
  • বাম জোড়ার জন্য প্রথম টেবিল: 179 সারি;
  • বাম যোগদানের জন্য দ্বিতীয় সারণী: 7 সারি।

EF কোর সংস্করণ: 2.2.1।

এসকিউএল সার্ভার সংস্করণ: এমএস এসকিউএল সার্ভার 2017 - 14 ... (উইন্ডোজ 10 এ)।

সমস্ত প্রাসঙ্গিক সারণীতে কেবলমাত্র প্রাথমিক কীগুলিতে সূচি ছিল।

আমার উপসংহার: উত্সাহিত এসকিউএল দেখার জন্য এটি সর্বদা সুপারিশ করা হয় যেহেতু এটি সত্যিই আলাদা হতে পারে।


[1] মজার বিষয় যথেষ্ট, এমএস এসকিউএল সার্ভার ম্যানেজমেন্ট স্টুডিওতে 'ক্লায়েন্টের পরিসংখ্যান' সেট করার সময়, আমি একটি বিপরীত প্রবণতা দেখতে পেলাম; অর্থাত্ ক্রস প্রয়োগ ব্যতীত সমাধানটির শেষ রানটি 1s এরও বেশি সময় নিয়েছিল। আমি মনে করি যে এখানে কিছু ভুল হচ্ছে - সম্ভবত আমার সেটআপটি দিয়ে।

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