Oracle
 sql >> база данни >  >> RDS >> Oracle

самостоятелно присъединяване срещу вътрешно присъединяване

Намирам за полезно да мисля за всички таблици в израза SELECT като за представяне на техните собствени набори от данни.

Преди да приложите каквито и да било условия, можете да мислите за всеки набор от данни като пълен (цялата таблица, например).

Присъединяването е само един от няколкото начина да започнете да прецизирате тези набори от данни, за да намерите информацията, която наистина искате.

Въпреки че схемата на база данни може да бъде проектирана с определени връзки (първичен ключ <-> външен ключ), тези връзки наистина съществуват само в контекста на конкретна заявка. Писателят на заявка може да свърже каквото си иска с каквото си поиска. Ще дам пример за това по-късно...

INNER JOIN свързва две таблици една с друга. Често има множество операции JOIN в една заявка за свързване на множество таблици. Може да стане толкова сложно, колкото трябва. За прост пример разгледайте следните три таблици...

СТУДЕНТ| STUDENTID | ФАМИЛНО ИМЕ | СОБСТВЕНО ИМЕ |------------------------------------ 1 | Смит | Йоан 2 | Пател | Санджай 3 | Лий | Кевин 4 | Джаксън | Стивън 
ЗАПИСВАНЕ| ИДЕНТИФИКАТОР НА ЗАПИСВАНЕ | STUDENTID | CLASSID |-------------------------------------------- 1 | 2 | 3 2 | 3 | 1 3 | 4 | 2 
<предварителен код>КЛАС| CLASSID | КУРС | ПРОФЕСОР |-------------------------------- 1 | CS 101 | Смит 2 | CS 201 | Ганди 3 | CS 301 | Макдевид 4 | CS 401 | Мартинез

Таблицата STUDENT и таблицата CLASS са проектирани да се свързват една с друга чрез таблицата ЗАПИСАНЕ. Този вид таблица се нарича Свързваща таблица .

За да напишете заявка за показване на всички ученици и класовете, в които са записани, ще използвате две вътрешни съединения...

ИЗБЕРЕТЕ stud.LASTNAME, stud.FIRSTNAME, class.COURSE, class.PROFESSORFROM STUDENT studINNER JOIN EROLLMENT enr ON stud.STUDENTID =enr.STUDENTIDINNER JOIN CLASS class ON class.CLASSID =enr.CLASSID; 

Прочетете внимателно горното и трябва да видите какво се случва. Това, което ще получите в замяна, е следният набор от данни...

<предварителен код> | ФАМИЛНО ИМЕ | СОБСТВЕНО ИМЕ | КУРС | ПРОФЕСОР | -------------------------------------------- Пател | Санджай | CS 301 | Макдевид Лий | Кевин | CS 101 | Смит Джаксън | Стивън | CS 201 | Ганди

С помощта на клаузите JOIN ние ограничихме наборите от данни и на трите таблици само до онези, които съвпадат помежду си. „Съвпаденията“ се дефинират чрез ON клаузи. Обърнете внимание, че ако изпълните тази заявка, не бихте го направили вижте реда CLASSID 4 от таблицата CLASS или реда STUDENTID 1 от таблицата STUDENT, защото тези идентификатори не съществуват в съвпаденията (в този случай таблицата ЗА ЗАПИСВАНЕ). Погледнете в "ЛЯВО"/"ДЕСНО"/"ПЪЛНО ВЪНШНО" СЪЕДИНЯВАНЕ за повече информация как да направите това да работи малко по-различно.

Моля, имайте предвид, че според моите коментари за „връзки“ по-рано, няма никаква причина защо не можете да изпълните заявка, свързваща таблицата STUDENT и таблицата CLASS директно върху колоните LASTNAME и PROFESSOR. Тези две колони съвпадат по тип данни и вижте това! Те дори имат обща стойност! Това вероятно ще бъде странен набор от данни, който да получите в замяна. Искам да кажа, че може да се направи и никога не знаете какви нужди може да имате в бъдеще за интересни връзки във вашите данни. Разберете дизайна на базата данни, но не мислете за „връзките“ като за правила, които не могат да бъдат пренебрегнати.

Междувременно... ПРИСЪЕДИНЕТЕ СЕ!

Разгледайте следната таблица...

<предварителен код>ЛИЦЕ| ПЕРСОНИД | FAMILYID | ИМЕ |-------------------------------- 1 | 1 | Йоан 2 | 1 | Брин 3 | 2 | Арпан 4 | 2 | Стив 5 | 2 | Тим 6 | 3 | Бека

Ако се почувствате толкова склонни да направите база данни за всички хора, които познавате и кои от тях са в едно семейство, това може да изглежда така.

Ако искате да върнете един човек, PERSONID 4, например, бихте написали...

SELECT * FROM PERSON WHERE PERSONID =4; 

Ще научите, че той е в семейството с FAMILYID 2. След това ще намерите всички от ЛИЦАТА в семейството му бихте написали...

SELECT * FROM PERSON WHERE FAMILYID =2; 

Готово и готово! SQL, разбира се, може да постигне това с една заявка, използвайки, познахте, SELF JOIN.

Какво наистина задейства нуждата от САМОСЪЕДИНЕНИЕ тук е, че таблицата съдържа уникална колона (PERSONID) и колона, която служи като нещо като "Категория" (FAMILYID). Тази концепция се нарича кардиналност и в този случай представлява едно към много или 1:M връзка. Има самоедна на всекиЛИЦЕ но има мнаго ЛИЦА вСЕМЕЙСТВО .

И така, това, което искаме да върнем, евсичко от членовете на едно семейство, ако еседно PERSONID на член на семейството е известен...

SELECT fam.*FROM PERSON perJOIN PERSON fam ON per.FamilyID =fam.FamilyIDWHERE per.PERSONID =4; 

Ето какво ще получите...

<предварителен код>| ПЕРСОНИД | FAMILYID | ИМЕ |-------------------------------- 3 | 2 | Арпан 4 | 2 | Стив 5 | 2 | Тим

Нека отбележим няколко неща. Думите САМ ПРИСЪЕДИНЕТЕ не се срещат никъде. Това е така, защото САМОСЪЕДИНЕНИЕ е само концепция. Думата ПРИСЪЕДИНИ в заявката по-горе може да е ЛЯВО СЪЕДИНЯВАНЕ вместо това и щяха да се случат различни неща. Смисълът на САМОСЪЕДИНЕНЕ е, че използвате една и съща таблица два пъти.

Помислете за моята кутия за сапун от преди за набори от данни. Тук започнахме с набора от данни от таблицата PERSON два пъти. Нито пример от набора от данни засяга другия, освен ако не кажем, че го прави.

Нека започнем от дъното на заявката. Назам наборът от данни е ограничен само до онези редове, където PERSONID =4. Познавайки таблицата, знаем, че ще върне точно един ред. Колоната FAMILYID в този ред има стойност 2.

В клаузата ON ние ограничаваме fam набор от данни (който в този момент все още е цялата таблица PERSON) само на тези редове, където стойността на FAMILYID съвпада с един или повече от FAMILYIDs наза набор от данни. Както обсъдихме, ние знаем козата наборът от данни има само един ред, следователно една стойност на FAMILYID. Затова фамита наборът от данни вече съдържа само редове, където FAMILYID =2.

И накрая, в горната част на заявката ние ИЗБИРАМЕ всички редове в fam набор от данни.

Ето! Две заявки в една.

В заключение, INNER JOIN е един от няколкото вида операции JOIN. Бихсилно предлагам да прочетете допълнително за ЛЯВИ, ДЕСНИ и ПЪЛНИ ВЪНШНИ СЪЕДИНЕНИЯ (които заедно се наричат ​​ВЪНШНИ СЪЕДИНЕНИЯ ). Аз лично пропуснах възможност за работа, защото имах слаби познания за OUTER JOIN веднъж и няма да позволя това да се случи отново!

САМОСЪЕДИНЕНИЕ е просто всяка операция JOIN, при която свързвате таблица със самата нея. Начинът, по който избирате да ПРИСЪЕДИНИТЕ тази таблица към самата нея, може да използва INNER JOIN или ВЪНШНО СЪЕДИНЯВАНЕ. Имайте предвид, че с САМОСЪЕДИНЕНИЕ , за да не объркате вашия SQL двигател, койтотрябва използвайте псевдоними на таблици (fam и per от по-горе. Измислете каквото има смисъл за вашата заявка) или няма начин да разграничите различните версии от същата таблица.

Сега, след като разбирате разликата, отворете добре ума си и осъзнайте, че една единствена заявка може да съдържа всички различни видове JOIN наведнъж. Въпросът е само какви данни искате и как трябва да изкривите заявката си, за да я получите. Ако откриете, че изпълнявате една заявка и вземате резултата от тази заявка и го използвате като вход за друга заявка, вероятно можете да използвате JOIN вместо това да го направи една заявка.

За да си поиграете с SQL, опитайте да посетите W3Schools.com Там има локално съхранена база данни с куп таблици, които са проектирани да се свързват една с друга по различни начини и е пълна с данни! Можете да СЪЗДАВАТЕ, ПУСКАТЕ, ВМЪКВАТЕ, АКТУАЛИЗИРАТЕ и ИЗБИРАТЕ всичко, което искате, и да върнете базата данни обратно към нейната подразбиране по всяко време. Опитайте всички видове SQL, за да експериментирате с различни трикове. Самият аз научих много там.

Съжалявам, ако това е малко многословно, но аз лично се борех с концепцията за JOINs, когато започвах да уча SQL и обясняването на концепция с помощта на куп други сложни концепции ме затъна. Най-добре е понякога да започнете отдолу.

Надявам се да помогне. Ако можете да поставите JOIN в задния си джоб, можете да направите магия със SQL!

Приятно запитване!



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. ИЗБЕРЕТЕ INTO с помощта на Oracle

  2. java.lang.ArrayIndexOutOfBoundsException в oracle.jdbc.driver.T4CTTIrxd.readBitVector(T4CTTIrxd.java:135)

  3. Как да съединя 2 заявки с различен брой записи и колони в oracle sql?

  4. Oracle SQL:Получаване на грешка „няма съответстващ уникален или първичен ключ“ и не знам защо

  5. Как да получите работни дни или часове между две дати