এসকিউএল যোগ দিন - যেখানে ক্লজ বনাম বনাম


687

এটি পড়ার পরে, এটি সুস্পষ্ট বনাম ইমপ্লিপ এসকিউএল যোগদানের একটি সদৃশ নয় । উত্তর সম্পর্কিত হতে পারে (বা এমনকি একই) তবে প্রশ্নটি আলাদা।


পার্থক্য কি এবং প্রতিটি মধ্যে কি করা উচিত?

যদি আমি তত্ত্বটি সঠিকভাবে বুঝতে পারি তবে ক্যোয়ারী অপ্টিমাইজারটি উভয়কে আন্তরজাগরণযোগ্যভাবে ব্যবহার করতে সক্ষম হওয়া উচিত।


2
কেবলমাত্র ভবিষ্যতের পাঠক এবং আপনার তথ্যের জন্য আপনার স্কেল কার্যকর করার ক্রমটি পড়া উচিত read অন্তর্নিহিত পার্থক্য বুঝতে এটি আপনাকে আরও সুনির্দিষ্টভাবে সহায়তা করবে।
রাহুল নীখরা

উত্তর:


869

এগুলো এক জিনিস না.

এই প্রশ্নগুলি বিবেচনা করুন:

SELECT *
FROM Orders
LEFT JOIN OrderLines ON OrderLines.OrderID=Orders.ID
WHERE Orders.ID = 12345

এবং

SELECT *
FROM Orders
LEFT JOIN OrderLines ON OrderLines.OrderID=Orders.ID 
    AND Orders.ID = 12345

প্রথমটি অর্ডার সংখ্যার জন্য একটি অর্ডার এবং এর লাইনগুলি যদি থাকে তবে তা ফেরত দেবে 12345। দ্বিতীয়টি সমস্ত আদেশ ফেরত দেবে, তবে কেবল অর্ডারের 12345সাথে কোনও লাইন যুক্ত থাকবে।

একটি সঙ্গে INNER JOIN, ধারাগুলি কার্যকরভাবে সমতুল্য। তবে, কারণ তারা কার্যত একই, কারণ তারা একই ফলাফল দেয়, এর অর্থ এই নয় যে দুটি ধরণের ধারাগুলির একই শব্দার্থক অর্থ রয়েছে।


83
আপনি কি অভ্যন্তরীণ যোগদানের জন্য "অন" ধারাটিতে "ক্লজ" রেখে আরও ভাল পারফরম্যান্স পাবেন?
ফিস্টঅফফুরি 16

96
@ ফিস্টঅফফুরি এসকিএল সার্ভার একটি ক্যোয়ারী অপটিমাইজার পদ্ধতি ব্যবহার করে যা আপনার কোডটিকে এটি করতে পারে সর্বোত্তম এক্সিকিউশন প্ল্যান তৈরি করতে সংকলন এবং মূল্যায়ন করে। এটি নিখুঁত নয়, তবে বেশিরভাগ সময় এটি গুরুত্ব দেয় না এবং আপনি উভয় উপায়ে একই কার্যকরকরণ পরিকল্পনা পাবেন।
জোয়েল কোহোর্ন

18
পোস্টগ্রিসে আমি উল্লেখ করেছি যে সেগুলি সমতুল্য নয় এবং এর ফলে বিভিন্ন প্রশ্নের পরিকল্পনা রয়েছে। আপনি যদি অন ব্যবহার করেন তবে এর ফলশ্রুতিতে ব্যবহারের ফলস্বরূপ। আপনি যদি ব্যবহার করেন তবে এটি একটি হ্যাশ ব্যবহার করেছে। ম্যাটেরিয়ালাইজের একটি খারাপ পরিস্থিতি ছিল যা হ্যাশের চেয়ে 10x বেশি ব্যয়বহুল ছিল। এটি একক আইডির চেয়ে আইডির একটি সেট ব্যবহার করছিল।
জেমস হাচিসন

13
@ জেমস হাচিসন এর মতো পর্যবেক্ষণমূলক আচরণের ভিত্তিতে নির্ভরযোগ্য পারফরম্যান্স সাধারণকরণ করা শক্ত make একদিন যা সত্য ছিল তা পরের দিন ভুল হতে থাকে, কারণ এটি নথিভুক্ত আচরণের চেয়ে বাস্তবায়নের বিশদ। ডেটাবেস দলগুলি সর্বদা অপ্টিমাইজারের কার্যকারিতা উন্নত করার জন্য স্থানগুলি সন্ধান করে। ওএন আচরণটি WHERE এর সাথে মেলে যদি উন্নত না হয় তবে আমি অবাক হব। এটি "সাধারণ কার্যকারিতা উন্নতি" এর মতো সংস্করণ থেকে অন্য সংস্করণে প্রকাশিত নোটগুলিতে অন্য কোথাও প্রদর্শিত হতে পারে না
জোয়েল কোহোর্ন

4
@ ফাইহোরান এটি স্কিল সার্ভারের কাজ করে না। পরিসংখ্যান দেখায় যে এটি সহায়ক হতে পারে It
জোয়েল কোহোর্ন

362
  • অভ্যন্তরীণ যোগদানের জন্য কিছু যায় আসে না
  • বাইরের যোগদানের জন্য বিষয়গুলি

    ক। WHEREধারা: যোগদানের পরে । যোগদানের পরে রেকর্ডগুলি ফিল্টার করা হবে।

    খ। ONধারা - যোগদানের আগে যোগদানের আগে রেকর্ডস (ডান টেবিল থেকে) ফিল্টার করা হবে। এটি ফলাফলটি নাল হিসাবে শেষ হতে পারে (যেহেতু OUTER যোগদান করে)।



উদাহরণ : নীচের টেবিলগুলি বিবেচনা করুন:

    1. documents:
     | id    | name        |
     --------|-------------|
     | 1     | Document1   |
     | 2     | Document2   |
     | 3     | Document3   |
     | 4     | Document4   |
     | 5     | Document5   |


    2. downloads:
     | id   | document_id   | username |
     |------|---------------|----------|
     | 1    | 1             | sandeep  |
     | 2    | 1             | simi     |
     | 3    | 2             | sandeep  |
     | 4    | 2             | reya     |
     | 5    | 3             | simi     |

ক) WHEREঅনুচ্ছেদের ভিতরে :

  SELECT documents.name, downloads.id
    FROM documents
    LEFT OUTER JOIN downloads
      ON documents.id = downloads.document_id
    WHERE username = 'sandeep'

 For above query the intermediate join table will look like this.

    | id(from documents) | name         | id (from downloads) | document_id | username |
    |--------------------|--------------|---------------------|-------------|----------|
    | 1                  | Document1    | 1                   | 1           | sandeep  |
    | 1                  | Document1    | 2                   | 1           | simi     |
    | 2                  | Document2    | 3                   | 2           | sandeep  |
    | 2                  | Document2    | 4                   | 2           | reya     |
    | 3                  | Document3    | 5                   | 3           | simi     |
    | 4                  | Document4    | NULL                | NULL        | NULL     |
    | 5                  | Document5    | NULL                | NULL        | NULL     |

  After applying the `WHERE` clause and selecting the listed attributes, the result will be: 

   | name         | id |
   |--------------|----|
   | Document1    | 1  |
   | Document2    | 3  | 

খ) JOINঅনুচ্ছেদের ভিতরে

  SELECT documents.name, downloads.id
  FROM documents
    LEFT OUTER JOIN downloads
      ON documents.id = downloads.document_id
        AND username = 'sandeep'

For above query the intermediate join table will look like this.

    | id(from documents) | name         | id (from downloads) | document_id | username |
    |--------------------|--------------|---------------------|-------------|----------|
    | 1                  | Document1    | 1                   | 1           | sandeep  |
    | 2                  | Document2    | 3                   | 2           | sandeep  |
    | 3                  | Document3    | NULL                | NULL        | NULL     |
    | 4                  | Document4    | NULL                | NULL        | NULL     |
    | 5                  | Document5    | NULL                | NULL        | NULL     |

Notice how the rows in `documents` that did not match both the conditions are populated with `NULL` values.

After Selecting the listed attributes, the result will be: 

   | name       | id   |
   |------------|------|
   |  Document1 | 1    |
   |  Document2 | 3    | 
   |  Document3 | NULL |
   |  Document4 | NULL | 
   |  Document5 | NULL | 

40
আইএমও এটি সেরা উত্তর কারণ এটি অন্যান্য জনপ্রিয় উত্তরের 'হুডের নীচে' কী চলছে তা স্পষ্টভাবে দেখায়।
psrpsrpsr

1
দুর্দান্ত ব্যাখ্যা .... ভাল হয়েছে! - শুধু কৌতূহল যে আপনি এটি পেতে কি করলেন intermediate join table?. কিছু 'ব্যাখ্যা' আদেশ?
ম্যানুয়েল জর্ডান 21

1
@ ম্যানুয়েলজর্ডান না, এটি কেবল ব্যাখ্যার জন্য। একটি মধ্যবর্তী টেবিল তৈরি করার চেয়ে একটি ডাটাবেস আরও কিছু পারফরম্যান্স করতে পারে।
সন্দীপ জিন্দাল

বুঝেছি, আমি ধরে নিয়েছি সম্ভবত কোনও তৃতীয় সরঞ্জাম ব্যবহৃত হয়েছিল।
ম্যানুয়েল জর্ডান

145

উপর INNER JOINগুলি তারা বিনিমেয়, এবং অপটিমাইজার তাদের স্বেচ্ছায় নতুন করে সাজানো হবে।

উপর OUTER JOINগুলি, তারা উপর যা পার্শ্ব যোগদানের তারা উপর নির্ভর করে নির্ভর করে অগত্যা বিনিমেয় নয়।

আমি তাদের পাঠযোগ্যতার উপর নির্ভর করে উভয় জায়গায় রেখেছি।



এটি সম্ভবত যেখানে স্পষ্টতই লিনক-টু-সত্তা ল্যাম্বডা অভিব্যক্তির দফায় অনেক স্পষ্টOrders.Join( OrderLines, x => x.ID, x => OrderID, (o,l) => new {Orders = o, Lines = l}).Where( ol => ol.Orders.ID = 12345)
ত্রিণকো

49

আমি যেভাবে এটি করি তা হ'ল:

  • ONআপনি যদি কোনও কাজটি করে থাকেন তবে সর্বদা যোগদানের শর্তটিকে ক্লজটিতে রাখুন INNER JOIN। সুতরাং ওএন ক্লজে কোনও WHERE শর্ত যুক্ত করবেন না, সেগুলিকে WHEREক্লজটিতে রাখুন।

  • যদি আপনি একটি করে থাকেন তবে ডানদিকে টেবিলের জন্য যে LEFT JOINকোনও শর্ত যুক্ত করুনON তবে যোগদানের যুক্ত করুন। এটি আবশ্যক, কারণ যোগদানের ডান পাশের উল্লেখ করা এমন একটি ক্লজ যুক্ত করা জোড়কে একটি INNER যোগদানের সাথে রূপান্তর করবে।

    ব্যতিক্রমটি যখন আপনি কোনও সারণীতে নেই এমন রেকর্ডগুলি সন্ধান করছেন। আপনি একটি অনন্য শনাক্তকারী রেফারেন্স যোগ হবে ডানদিকে (যে কখনও শূন্য নয়) WHERE বাক্যাংশ এই পথ টেবিল যোগদান করুন: WHERE t2.idfield IS NULL। সুতরাং, কেবলমাত্র যুক্ত হওয়ার ডান দিকে কোনও টেবিলের উল্লেখ করার পরে সেই রেকর্ডগুলি সারণীতে নেই যা খুঁজে পাওয়া উচিত।


8
এটি এখনও পর্যন্ত আমি এটি পড়েছি সেরা উত্তর। একবার আপনার মস্তিষ্ক বুঝতে পারে বাম যোগদান পুরোটাই জ্ঞান করে তোলে যাচ্ছে বাম টেবিলে সব সারি ফিরে যান এবং আপনি পরে ফিল্টার করতে আছে।
নিক লারসেন

যদি আপনি কোনও শনাক্তযোগ্য কলাম সহ একটি টেবিলের সাথে বাইরের অংশে যোগদান করেন, তবে আপনি সেই কলামটি অভ্যন্তরীণ জোড় না করেই "কমে" যেতে পারেন? এটি কেবলমাত্র নির্দিষ্ট টেবিলে নেই এমন রেকর্ডগুলির সন্ধান করছে না। আপনি ১ টি সন্ধান করতে পারেন অস্তিত্বহীন ২. এর কোন মূল্য নেই।
নিয়ার

আমি বলতে চাইছি আপনি উভয়ের জন্য সন্ধান করতে পারেন: "১. অস্তিত্ব নেই ২. একসাথে" এর কোনও মূল্য নেই। " এবং ক্ষেত্রটি আইডফিল্ড নয় এমন ক্ষেত্রে এটি প্রযোজ্য।
নিয়ার

আমি যেমন এই মামলার মুখোমুখি হয়েছি: জরুরী যোগাযোগ ব্যতীত নতুনদের (ডেটা এখনও ইনপুট করা হয়নি) সহ অংশগ্রহণকারীদের সন্ধান করছি।
কাছাকাছি

30

অভ্যন্তরীণ যোগদানের সময়, তারা একই জিনিস বোঝায়। তবে আপনি যেখানে ওভার ক্লজটি যেখানে বনামের শর্তটিতে যোগদানের শর্তটি রেখেছেন তার উপর নির্ভর করে আপনি একটি বহিরাগত যোগদানের বিভিন্ন ফলাফল পাবেন। কটাক্ষপাত এই সংশ্লিষ্ট প্রশ্ন এবং উত্তর (আমার দ্বারা)।

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


26

এটি একটি খুব সাধারণ প্রশ্ন, সুতরাং এই উত্তরটি আমার লেখা নিবন্ধের উপর ভিত্তি করে ।

টেবিল সম্পর্ক

আমাদের নিম্নোক্ত postএবং post_commentসারণীগুলি বিবেচনা করে:

<কোড> পোস্ট </ কোড> এবং <কোড> পোস্ট_কমেন্ট </ কোড> সারণী

postনিম্নলিখিত রেকর্ড রয়েছে:

| id | title     |
|----|-----------|
| 1  | Java      |
| 2  | Hibernate |
| 3  | JPA       |

এবং এর post_commentনিম্নলিখিত তিনটি সারি রয়েছে:

| id | review    | post_id |
|----|-----------|---------|
| 1  | Good      | 1       |
| 2  | Excellent | 1       |
| 3  | Awesome   | 2       |

এসকিউএল আন্তঃ যোগদান

এসকিউএল যোগদানের ধারাটি আপনাকে বিভিন্ন সারণির সাথে সম্পর্কিত সারিগুলি সংযুক্ত করতে দেয়। উদাহরণস্বরূপ, একটি ক্রস যোগ যোগদানকারী দুটি টেবিলের মধ্যে সারিগুলির সমস্ত সম্ভাব্য সংমিশ্রণযুক্ত কার্টেসিয়ান পণ্য তৈরি করবে।

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

এসকিউএল অভ্যন্তরীণ যোগদান আমাদের বিধি দ্বারা নির্দিষ্ট করা শর্তের ভিত্তিতে দুটি টেবিলের সাথে যুক্ত হওয়ার কার্টেসিয়ান পণ্য ফিল্টার করতে দেয় allows

এসকিউএল ইনার যোগ দিন - "সর্বদা সত্য" শর্ত

যদি আপনি একটি "সর্বদা সত্য" শর্ত সরবরাহ করেন তবে অন্তর্ভুক্ত যোগদানকারী রেকর্ডগুলি ফিল্টার করবে না এবং ফলাফল সেটটিতে দুটি যোগদানের টেবিলের কার্টেসিয়ান পণ্য থাকবে।

উদাহরণস্বরূপ, আমরা যদি নিম্নলিখিত এসকিউএল ইনার জয়েন কোয়েরি কার্যকর করি:

SELECT
   p.id AS "p.id",
   pc.id AS "pc.id"
FROM post p
INNER JOIN post_comment pc ON 1 = 1

আমরা সমস্ত সংযুক্তি postএবং post_commentরেকর্ডগুলি পেয়ে যাব :

| p.id    | pc.id      |
|---------|------------|
| 1       | 1          |
| 1       | 2          |
| 1       | 3          |
| 2       | 1          |
| 2       | 2          |
| 2       | 3          |
| 3       | 1          |
| 3       | 2          |
| 3       | 3          |

সুতরাং, যদি অন দফা শর্তটি "সর্বদা সত্য" হয়, তবে অন্তর্ভুক্ত হওয়া সহজভাবে একটি ক্রস যোগ কোয়ের সমতুল্য:

SELECT
   p.id AS "p.id",
   pc.id AS "pc.id"
FROM post p
CROSS JOIN post_comment
WHERE 1 = 1
ORDER BY p.id, pc.id

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

অন্যদিকে, যদি ওএন ক্লজ শর্তটি "সর্বদা মিথ্যা" থাকে, তবে যুক্ত হওয়া সমস্ত রেকর্ডগুলি ফিল্টার করা হতে চলেছে এবং ফলাফল সেটটি খালি হবে।

সুতরাং, আমরা যদি নিম্নলিখিত এসকিউএল ইনার জয়েন কোয়েরি কার্যকর করি:

SELECT
   p.id AS "p.id",
   pc.id AS "pc.id"
FROM post p
INNER JOIN post_comment pc ON 1 = 0
ORDER BY p.id, pc.id

আমরা কোনও ফল ফিরে পাব না:

| p.id    | pc.id      |
|---------|------------|

কারণ উপরের ক্যোয়ারীটি নীচের ক্রস যোগ কোয়ের সমান:

SELECT
   p.id AS "p.id",
   pc.id AS "pc.id"
FROM post p
CROSS JOIN post_comment
WHERE 1 = 0
ORDER BY p.id, pc.id

এসকিউএল ইনার যোগ দিন - বিদেশী কী এবং প্রাথমিক কী কলামগুলি ব্যবহার করে ক্লোজ করুন use

নিম্নলিখিত শুল্কের মধ্যে সর্বাধিক সাধারণ শর্তটি হ'ল সন্তানের টেবিলে বিদেশী কী কলামটি পিতামাতার সারণীতে প্রাথমিক কী কলামের সাথে মেলে যা নিম্নলিখিত কোয়েরির দ্বারা চিত্রিত হয়েছে:

SELECT
   p.id AS "p.id",
   pc.post_id AS "pc.post_id",
   pc.id AS "pc.id",
   p.title AS "p.title",
   pc.review  AS "pc.review"
FROM post p
INNER JOIN post_comment pc ON pc.post_id = p.id
ORDER BY p.id, pc.id

উপরের এসকিউএল ইনার জয়েন কোয়েরি কার্যকর করার সময়, আমরা নিম্নলিখিত ফলাফল সেট পাই:

| p.id    | pc.post_id | pc.id      | p.title    | pc.review |
|---------|------------|------------|------------|-----------|
| 1       | 1          | 1          | Java       | Good      |
| 1       | 1          | 2          | Java       | Excellent |
| 2       | 2          | 3          | Hibernate  | Awesome   |

সুতরাং, ওএন ক্লজ শর্তের সাথে মেলে এমন রেকর্ডগুলিই ক্যোরি রেজাল্ট সেটে অন্তর্ভুক্ত রয়েছে। আমাদের ক্ষেত্রে, ফলাফল সেটটিতে postতাদের post_commentরেকর্ড সহ সমস্ত কিছু থাকে । যে postসারিগুলির কোনও সম্পর্কিত নেই post_commentতারা বাদ দেওয়া হয়েছে কারণ তারা অন ক্লোজ শর্তটি পূরণ করতে পারে না।

আবার, উপরের এসকিউএল ইনার জয়েন কোয়েরিটি নিম্নলিখিত ক্রস যোগ কোয়েরির সমতুল্য:

SELECT
   p.id AS "p.id",
   pc.post_id AS "pc.post_id",
   pc.id AS "pc.id",
   p.title AS "p.title",
   pc.review  AS "pc.review"
FROM post p, post_comment pc
WHERE pc.post_id = p.id

অবিঘ্নিত সারিগুলি হ'ল যেখানে বিধিটি পূরণ করে এবং কেবলমাত্র এই রেকর্ডগুলি ফলাফল সেটে অন্তর্ভুক্ত হতে চলেছে। অভ্যন্তরীণ যোগ দারা কীভাবে কাজ করে তা কল্পনা করার সর্বোত্তম উপায়।

| পি.আইডি | pc.post_id | pc.id | p.title | pc.review |
| ------ | ------------ | ------- | ----------- | --------- - |
| 1 | 1 | 1 | জাভা | ভাল |
| 1 | 1 | 2 | জাভা | দুর্দান্ত |
| 1 | 2 | 3 | জাভা | অসাধারণ | 
| 2 | 1 | 1 | হাইবারনেট | ভাল | 
| 2 | 1 | 2 | হাইবারনেট | দুর্দান্ত |
| 2 | 2 | 3 | হাইবারনেট | অসাধারণ |
| 3 | 1 | 1 | জেপিএ | ভাল | 
| 3 | 1 | 2 | জেপিএ | দুর্দান্ত | 
| 3 | 2 | 3 | জেপিএ | অসাধারণ |

উপসংহার

একটি অন্তর্ভুক্ত যোগদানের বিবৃতিটি INNER যোগদানের ক্যোয়ারীর অন ক্লজে আপনি যে একই শর্তে ব্যবহার করেছেন একই শর্তের সাথে একটি পরিচ্ছন্ন যোগ হিসাবে একটি ক্রস যোগ হিসাবে পুনরায় লেখা যেতে পারে।

এটি কেবল অন্তর্ভুক্ত যোগদানের জন্যই প্রযোজ্য নয়, বাহ্যিক যোগদানের জন্য নয়।


11

তার মাঝে মহান পার্থক্য নেই যেখানে দফা বনাম দফা উপর যখন এটি বাম যোগদানের জন্য আসে।

এখানে উদাহরণ:

mysql> desc t1; 
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | NO   |     | NULL    |       |
| fid   | int(11)     | NO   |     | NULL    |       |
| v     | varchar(20) | NO   |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+

এখানে ফিড টেবিল টি 2 এর আইডি রয়েছে।

mysql> desc t2;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | NO   |     | NULL    |       |
| v     | varchar(10) | NO   |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

"ধারাতে" প্রশ্ন:

mysql> SELECT * FROM `t1` left join t2 on fid = t2.id AND t1.v = 'K' 
    -> ;
+----+-----+---+------+------+
| id | fid | v | id   | v    |
+----+-----+---+------+------+
|  1 |   1 | H | NULL | NULL |
|  2 |   1 | B | NULL | NULL |
|  3 |   2 | H | NULL | NULL |
|  4 |   7 | K | NULL | NULL |
|  5 |   5 | L | NULL | NULL |
+----+-----+---+------+------+
5 rows in set (0.00 sec)

"যেখানে ধারা" সম্পর্কিত প্রশ্ন:

mysql> SELECT * FROM `t1` left join t2 on fid = t2.id where t1.v = 'K';
+----+-----+---+------+------+
| id | fid | v | id   | v    |
+----+-----+---+------+------+
|  4 |   7 | K | NULL | NULL |
+----+-----+---+------+------+
1 row in set (0.00 sec)

এটা পরিষ্কার যে, প্রথম ক্যোয়ারী টি 1 থেকে রেকর্ড এবং তার উপর নির্ভরশীল সারি টি 2 থেকে, যদি কোনও থাকে, সারি টি 1.v = 'কে' এর জন্য দেয়।

দ্বিতীয় ক্যোয়ারী টি 1 থেকে সারিগুলি ফেরত দেয় তবে কেবল t1.v = 'কে' এর সাথে এর সাথে কোনও সম্পর্কিত সারি থাকবে।


9

অপ্টিমাইজারের ক্ষেত্রে, আপনি নিজের যোগদানের ধারাগুলি চালু বা WHERE- এর সাথে সংজ্ঞায়িত করেছেন কিনা তাতে কোনও পার্থক্য হওয়া উচিত নয়।

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


7

আসুন সেই টেবিলগুলি বিবেচনা করুন:

একজন

id | SomeData

বি

id | id_A | SomeOtherData

id_A টেবিলের জন্য একটি বিদেশী কী হচ্ছে A

এই কোয়েরিটি লিখছেন:

SELECT *
FROM A
LEFT JOIN B
ON A.id = B.id_A;

এই ফলাফল প্রদান করবে:

/ : part of the result
                                       B
                      +---------------------------------+
            A         |                                 |
+---------------------+-------+                         |
|/////////////////////|///////|                         |
|/////////////////////|///////|                         |
|/////////////////////|///////|                         |
|/////////////////////|///////|                         |
|/////////////////////+-------+-------------------------+
|/////////////////////////////|
+-----------------------------+

A তে তবে B এ যা নেই তার অর্থ হল বি এর জন্য নাল মান রয়েছে


এখন, এর একটি নির্দিষ্ট অংশ বিবেচনা করুন B.id_A, এবং এটি পূর্ববর্তী ফলাফল থেকে হাইলাইট করুন:

/ : part of the result
* : part of the result with the specific B.id_A
                                       B
                      +---------------------------------+
            A         |                                 |
+---------------------+-------+                         |
|/////////////////////|///////|                         |
|/////////////////////|///////|                         |
|/////////////////////+---+///|                         |
|/////////////////////|***|///|                         |
|/////////////////////+---+---+-------------------------+
|/////////////////////////////|
+-----------------------------+

এই কোয়েরিটি লিখছেন:

SELECT *
FROM A
LEFT JOIN B
ON A.id = B.id_A
AND B.id_A = SpecificPart;

এই ফলাফল প্রদান করবে:

/ : part of the result
* : part of the result with the specific B.id_A
                                       B
                      +---------------------------------+
            A         |                                 |
+---------------------+-------+                         |
|/////////////////////|       |                         |
|/////////////////////|       |                         |
|/////////////////////+---+   |                         |
|/////////////////////|***|   |                         |
|/////////////////////+---+---+-------------------------+
|/////////////////////////////|
+-----------------------------+

কারণ এটি অন্তর্ভুক্ত করে এমন মানগুলিকে সরিয়ে দেয় যা মান নেই B.id_A = SpecificPart


এখন, কোয়েরি এটিতে পরিবর্তন করুন:

SELECT *
FROM A
LEFT JOIN B
ON A.id = B.id_A
WHERE B.id_A = SpecificPart;

ফলাফল এখন:

/ : part of the result
* : part of the result with the specific B.id_A
                                       B
                      +---------------------------------+
            A         |                                 |
+---------------------+-------+                         |
|                     |       |                         |
|                     |       |                         |
|                     +---+   |                         |
|                     |***|   |                         |
|                     +---+---+-------------------------+
|                             |
+-----------------------------+

কারণ পুরো ফলাফলটি B.id_A = SpecificPartঅংশগুলিকে অপসারণের বিরুদ্ধে ফিল্টার করা হয়েছে B.id_A = NULL, যেগুলি বি তে নেই


4

আপনি কি ডেটা বা ফিল্টার ডেটাতে যোগদানের চেষ্টা করছেন?

পঠনযোগ্যতার জন্য যথাযথভাবে ও যেখানে এবং এই ক্ষেত্রে ব্যবহারের কেসগুলি বিচ্ছিন্ন করার পক্ষে এটি সবচেয়ে বোধগম্য।

  • চালু ডেটা যোগ করুন
  • WHERE এ ফিল্টার ডেটা

যেখানে জওআইএন শর্ত এবং ফিল্টারিংয়ের শর্তটি যেখানে রয়েছে সেখানে কোয়েরি পড়া খুব কঠিন হয়ে উঠতে পারে।

পারফরম্যান্স অনুযায়ী আপনার কোনও পার্থক্য দেখা উচিত নয়, যদিও বিভিন্ন ধরণের এসকিউএল কখনও কখনও কোয়েরি প্ল্যানিংকে ভিন্নভাবে পরিচালনা করে যাতে এটি চেষ্টা করার মতো হতে পারে ¯\_(ツ)_/¯ হতে পারে (ক্যোরির গতিতে প্রভাব ফেলতে ক্যাশে সম্পর্কে সচেতন হন)

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

আমি এ সম্পর্কে আরও গভীরতার পোস্টে লিখেছিলাম: https://dataschool.com/learn/differences-between-where-and-on-in-sql


2

এসকিউএল-তে 'WHERE' এবং 'ON' ধারাটি শর্তসাপেক্ষ স্টেটম্যান্টস, তবে তাদের মধ্যে প্রধান পার্থক্য হ'ল শর্ত নির্দিষ্ট করার জন্য 'যেখানে' ধারাটি নির্বাচন / আপডেট বিবৃতিতে ব্যবহৃত হয়, যেখানে 'ওএন' ধারা যোগদানকারীর ক্ষেত্রে ব্যবহৃত হয়, যেখানে টেবিলগুলি যুক্ত হওয়ার আগে এটি লক্ষ্য এবং উত্স সারণীতে রেকর্ডগুলি মিলছে কিনা তা যাচাই বা পরীক্ষা করে cks

উদাহরণস্বরূপ: - 'কোথায়'

SELECT * FROM employee WHERE employee_id=101

উদাহরণস্বরূপ: - 'চালু'

এখানে দুটি সারণী কর্মচারী এবং কর্মচারী_ বিবরণ রয়েছে, মেলানো কলামগুলি কর্মচারী_আইডি।

SELECT * FROM employee 
INNER JOIN employee_details 
ON employee.employee_id = employee_details.employee_id

আশা করি আমি আপনার প্রশ্নের উত্তর দিয়েছি। যে কোনও স্পষ্টতার জন্য ফিরে যান।


কিন্তু আপনি কিওয়ার্ডের WHEREজায়গায় ব্যবহার করতে পারেন ON, তাই না? sqlfiddle.com/#!2/ae5b0/14/0
কোয়ার্টি

1

আমি মনে করি এটি জয়েন সিকোয়েন্স ইফেক্ট। উপরের বাম যোগদানের ক্ষেত্রে, এসকিউএল ডো বামে প্রথমে যোগদান করুন এবং তারপরে যেখানে ফিল্টার করুন। ডাউনার ক্ষেত্রে, প্রথমে অর্ডারস.আইডি = 12345 সন্ধান করুন এবং তারপরে যোগদান করুন।


1

অভ্যন্তরীণ যোগদানের জন্য, WHEREএবং ONবিনিময়যোগ্যভাবে ব্যবহার করা যেতে পারে। প্রকৃতপক্ষে, এটি ONএকটি সম্পর্কযুক্ত subquery ব্যবহার করা সম্ভব । উদাহরণ স্বরূপ:

update mytable
set myscore=100
where exists (
select 1 from table1
inner join table2
on (table2.key = mytable.key)
inner join table3
on (table3.key = table2.key and table3.key = table1.key)
...
)

এটি (আইএমএইচও) একটি মানুষের কাছে সম্পূর্ণ বিভ্রান্তিকর এবং কোনও table1কিছুর সাথে লিঙ্ক করতে ভুলে যাওয়া খুব সহজ (কারণ "ড্রাইভার" টেবিলটির "অন" ধারা নেই) তবে এটি আইনী।


1

আরও ভাল পারফরম্যান্সের জন্য টেবিলগুলিতে জিনগুলির জন্য ব্যবহার করার জন্য একটি বিশেষ সূচীকরণ কলাম থাকা উচিত।

সুতরাং আপনি যে কলামটি শর্ত করেছেন সেগুলি যদি সেই সূচকযুক্ত কলামগুলির মধ্যে একটি না হয় তবে আমি সন্দেহ করি যে এটি যেখানে রাখা ভাল।

সুতরাং আপনি ইনডেক্সড কলামগুলি ব্যবহার করে যোগ দিন, তারপরে যোগদানের পরে আপনি কোনওটিই তালিকাভুক্ত কলামে শর্তটি চালাবেন না।


1

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


এটি ঠিক তাই নয় কারণ ডিবিএমএসগুলি "সাধারণত" অপ্টিমাইজ করে।
ফিলিপ্সি

1

আমি মনে করি এসকিউএল অপারেশনগুলির লজিকাল ক্রমের মাধ্যমে এই পার্থক্যটি সর্বোত্তমভাবে ব্যাখ্যা করা যেতে পারে , যা সরল:

  • FROM (যোগদান সহ)
  • WHERE
  • GROUP BY
  • মোট পরিমাণ
  • HAVING
  • WINDOW
  • SELECT
  • DISTINCT
  • UNION, INTERSECT,EXCEPT
  • ORDER BY
  • OFFSET
  • FETCH

যোগদানগুলি নির্বাচিত বিবৃতিটির একটি ধারা নয়, তবে এর মধ্যে একটি অপারেটর FROM। যেমন, সব ONসংশ্লিষ্ট একাত্মতার ক্লজ JOINঅপারেটর "ইতিমধ্যেই ঘটেছে" have কথাটি সময় যৌক্তিক প্রক্রিয়াকরণ ছুঁয়েছে দ্বারা WHEREদফা। এর অর্থ হ'ল একটি LEFT JOIN, উদাহরণস্বরূপ, বহিরাগত জোনের শব্দার্থক WHEREশব্দটি প্রয়োগের সময় ইতিমধ্যে সুখী হয়েছে ।

আমি এই ব্লগ পোস্টে নীচের উদাহরণটি আরও গভীরভাবে ব্যাখ্যা করেছি । এই কোয়েরিটি চলাকালীন:

SELECT a.actor_id, a.first_name, a.last_name, count(fa.film_id)
FROM actor a
LEFT JOIN film_actor fa ON a.actor_id = fa.actor_id
WHERE film_id < 10
GROUP BY a.actor_id, a.first_name, a.last_name
ORDER BY count(fa.film_id) ASC;

এর LEFT JOINসত্যিকারের কোনও কার্যকর প্রভাব নেই, কারণ এমনকি যদি কোনও অভিনেতা কোনও ছবিতে অভিনয় না করেন তবে অভিনেতা ফিল্টার করা হবে, যেমনটি FILM_IDহবে NULLএবং WHEREধারাটি এমন একটি সারি ফিল্টার করবে। ফলাফলটি এরকম কিছু:

ACTOR_ID  FIRST_NAME  LAST_NAME  COUNT
--------------------------------------
194       MERYL       ALLEN      1
198       MARY        KEITEL     1
30        SANDRA      PECK       1
85        MINNIE      ZELLWEGER  1
123       JULIANNE    DENCH      1

যেমন আমরা অভ্যন্তরীণ দুটি টেবিল যোগদান। আমরা যদি ক্লজটিতে ফিল্টার প্রিকেটটি সরিয়ে ফেলি ON, তবে এটি এখন বাহ্যিক যোগদানের জন্য একটি মানদণ্ডে পরিণত হয়:

SELECT a.actor_id, a.first_name, a.last_name, count(fa.film_id)
FROM actor a
LEFT JOIN film_actor fa ON a.actor_id = fa.actor_id
  AND film_id < 10
GROUP BY a.actor_id, a.first_name, a.last_name
ORDER BY count(fa.film_id) ASC;

অর্থ ফলাফলটিতে কোনও ফিল্ম ছাড়াই বা কোনও ফিল্ম ছাড়াই অভিনেতা থাকবে FILM_ID < 10

ACTOR_ID  FIRST_NAME  LAST_NAME     COUNT
-----------------------------------------
3         ED          CHASE         0
4         JENNIFER    DAVIS         0
5         JOHNNY      LOLLOBRIGIDA  0
6         BETTE       NICHOLSON     0
...
1         PENELOPE    GUINESS       1
200       THORA       TEMPLE        1
2         NICK        WAHLBERG      1
198       MARY        KEITEL        1

সংক্ষেপে

যুক্তিসঙ্গতভাবে যেখানে এটি সবচেয়ে সার্থক হয় সেখানে সর্বদা আপনার শিকারী রাখুন।


0

আপনার প্রশ্ন সম্পর্কে,

যতক্ষণ না আপনার সার্ভার এটি পেতে পারে ততক্ষণ এটি 'অন' বা 'যেখানে' অভ্যন্তরীণ যোগদানের ক্ষেত্রে একই:

select * from a inner join b on a.c = b.c

এবং

select * from a inner join b where a.c = b.c

'যেখানে' বিকল্পটি সমস্ত দোভাষী তা জানেন না তাই সম্ভবত এড়ানো উচিত। এবং অবশ্যই 'অন' ধারাটি আরও পরিষ্কার।


-5

এটি আমার সমাধান।

SELECT song_ID,songs.fullname, singers.fullname
FROM music JOIN songs ON songs.ID = music.song_ID  
JOIN singers ON singers.ID = music.singer_ID
GROUP BY songs.fullname

আপনি থাকতে হবেGROUP BY কাজের জন্য এটি পেতে।

এই সাহায্য আশা করি।


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