ЛЯВО ВЪНШНО СЪЕДИНЕНИЕ ЕКВИВАЛЕНТ

Имам таблица, която съдържа нулеви стойности. В таблицата ORDER имам 2 null в раздела PART_ID и 2 null стойности в CUSTOMER_ID.

И аз имам такъв тип запитване:

SELECT O.ORDER_ID , O.ORDER_DATE , O.CUST_ID, O.QUANTITY ,O.PART_ID ,
       C.CUST_NAME, C.CUST_CODE, P.PART_NAME, P.PART_CODE
FROM [ORDER] O
     LEFT OUTER JOIN PART P ON P.PART_ID = O.PART_ID
     LEFT OUTER JOIN CUSTOMER C ON C.CUST_ID = O.CUST_ID 

Ето го въпросът ми. Как мога да го направя, без да използвам външно присъединяване? Опитах твърде много неща, включително където не съществува или това;

SELECT *
FROM [ORDER] O ,CUSTOMER C, PART P
WHERE C.CUST_ID = (
  SELECT CUST_ID FROM CUSTOMER C WHERE O.CUST_ID = C.CUST_ID
) AND P.PART_ID = (SELECT PART_ID FROM PART P WHERE O.PART_ID = P.PART_ID) 

но не можах да намеря решение. Ако има решение как ще бъде?

(Забележка: това е домашна работа.)

Имам такава маса:

въведете описание на изображението тук

и лявото външно съединение дава това:

въведете описание на изображението тук

hw каза, че го направете, без да използвате външно съединение и вземете същата таблица, както лявото външно съединение дава. Но както казах, не можех. Аз също използвам MSSQL.


person developerCoder    schedule 22.03.2013    source източник
comment
Защо бихте искали?   -  person Yuck    schedule 22.03.2013
comment
Любопитно е да знам защо, като се има предвид, че синтаксисът е отхвърлен и обезсърчени от инструментите за статичен анализ   -  person Rowland Shaw    schedule 22.03.2013
comment
Също така OUTER в LEFT OUTER JOIN се подразбира. Можете просто да напишете LEFT JOIN вместо това.   -  person Yuck    schedule 22.03.2013
comment
Мисля, че коментарът на @Yuck е отговорът на вашия въпрос   -  person hop    schedule 22.03.2013
comment
@MarkBannister това ли е политиката на SO, която да изисква обяснение защо е зададен въпросът? Този въпрос ми изглежда доста ясен, без да давам повече предистория.   -  person topchef    schedule 22.03.2013
comment
@Yuck, искам да направя това, защото ми каза така. Накараха ме да правя без използване на външни съединения. Казаха ми, че мога да го направя с просто избиране и вътрешно присъединяване и вложена заявка. Опитвам се да го разбера, но не можах.   -  person developerCoder    schedule 22.03.2013
comment
@developerCoder: Кои са те и защо ви казват как да напишете заявка? Това домашно ли е?   -  person    schedule 22.03.2013
comment
@MarkBAnnister Да, това е домашното и се опитвам да разбера от 4 дни, но не можах.   -  person developerCoder    schedule 22.03.2013
comment
@developerCoder: Добре, гласуването против е премахнато.   -  person    schedule 22.03.2013
comment
Бог да те благослови, каква глупава задача. Никога няма да разбера защо инструкторите принуждават учениците си да вършат работа (IMHO) по грешен начин.   -  person Yuck    schedule 22.03.2013
comment
@Yuck Мисля, че ни принуждават да мислим различно, за да се подобрим.   -  person developerCoder    schedule 22.03.2013


Отговори (4)


Външното съединение създава супер-набор върху вътрешното съединение. Наистина, от Wikipedia: Лявото външно съединение връща всички стойности от вътрешно съединение плюс всички стойности в лявата таблица, които не съвпадат с дясната таблица.

Така че за моделиране на ляво външно съединение с помощта на вътрешно съединение може да се използва UNION на вътрешно съединение SELECT между едни и същи таблици със същото условие за свързване и друго SELECT от 1-ва таблица, която връща всички редове без съвпадение от дясната таблица (намалих вашия случай до едно ляво съединение):

SELECT O.ORDER_ID , O.ORDER_DATE , O.CUST_ID, O.QUANTITY ,O.PART_ID ,
       P.PART_NAME, P.PART_CODE
FROM [ORDER] O JOIN PART P ON P.PART_ID = O.PART_ID
UNION
SELECT O.ORDER_ID , O.ORDER_DATE , O.CUST_ID, O.QUANTITY ,O.PART_ID ,
       NULL, NULL 
FROM [ORDER] O
WHERE NOT EXISTS (SELECT 'found' FROM PART P WHERE P.PART_ID = O.PART_ID)
person topchef    schedule 22.03.2013
comment
@topchef Да, правилно е, но не даде CUST_NAME и CUST_CODE, как мога да добавя и тях? - person developerCoder; 22.03.2013
comment
тогава това ще бъде останалата част от домашното ви: просто следвайте същия подход - успех! - person topchef; 22.03.2013

Предполага се, че искате да получите съвпадения на колоните с NULL стойности, вместо те да се провалят. Ако е така, просто променете условията за присъединяване:

FROM [ORDER] O
     LEFT OUTER JOIN PART P
     ON P.PART_ID = O.PART_ID or (p.Part_id is NULL and o.Part_id is null)
     LEFT OUTER JOIN CUSTOMER C
     ON C.CUST_ID = O.CUST_ID or (c.cust_id is null and o.cust_id is null)

Основният проблем с този подход е, че много (повечето?) SQL машини няма да използват индекси за присъединяване.

person Gordon Linoff    schedule 22.03.2013

Има ли конкретна причина, поради която не искате да използвате външно свързване? Не е ли това резултатът, който искате? :

FROM [ORDER] O 
LEFT JOIN PART P 
ON P.PART_ID = O.PART_ID and P.PARTID is not null
LEFT JOIN CUSTOMER C 
ON C.CUST_ID = O.CUST_ID and C.CUSTID is not null
person Thanos Darkadakis    schedule 22.03.2013

Така че пълният отговор трябва да бъде така (след като моят учител даде резултати):

 SELECT O.ORDER_ID,O.ORDER_DATE,O.CUST_ID,
(SELECT C.CUST_CODE FROM CUSTOMER C WHERE C.CUST_ID=O.CUST_ID) AS CUST_CODE,
(SELECT C.CUST_NAME FROM CUSTOMER C WHERE C.CUST_ID=O.CUST_ID) AS CUST_NAME,
O.PART_ID,
(SELECT P.PART_CODE FROM PART P WHERE P.PART_ID = O.PART_ID ) AS PART_CODE,
(SELECT P.PART_NAME FROM PART P WHERE P.PART_ID = O.PART_ID ) AS PART_NAME,
O.QUANTITY

FROM [ORDER] O
person developerCoder    schedule 31.03.2013