Оптимизиране на union sql заявка

Правя UNION между 3 маси. За да ви поставим на снимката, една маса се счита за основна маса, а другите 2 маси се считат за подмаси. Двете подтаблици винаги имат еднакъв брой записи за всеки случай. Така че исках да направя обединение между тези 3 таблици, в това обединение бих искал да повторя информацията в колоната, извлечена в главната таблица, и да изброя информацията в 2 подтаблици, където всеки ред в подтаблица 1 съответства на реда в подтаблица 2. Не мога да поставя истинския код поради професионални причини, така че ето един прост пример, съответстващ на моя реален случай. Помислете за таблица, наречена Author (Author_ID, Author_FirstName, Author_LastName). Тази маса ще бъде нашата основна маса. Тогава помислете, че имаме таблица, наречена Адреси (Adress_ID, Street_Coord, Author_ID), това ще бъде нашата подтаблица 1. След това разгледайте таблицата, наречена Cities (City_ID, City_Name, Author_ID). Нашият автор X има 2 адреса в 2 града. Когато изпълня заявката си, получавам резултата R1, който е напълно логичен, но искам да модифицирам заявката си, за да получа резултата R2. Бихте ли ми помогнали да променя заявката си, за да получа резултата R2?

SQL заявка:

SELECT "Author"."Author_ID", "Author"."Author_FirstName", "Author.Author_LastName",
       TO_CHAR(NULL) AS "Street_Coord", TO_CHAR(NULL) AS "City_Name"
FROM "Author"
WHERE "Author"."Author_ID"='X'

UNION

SELECT TO_NUMBER(NULL) AS "Author_ID", TO_CHAR(NULL) AS "Author_FirstName", TO_CHAR(NULL) AS "Author_LastName", 
       "Adresses"."Street_Coord", TO_CHAR(NULL) AS "City_Name" 
FROM "Adresses"
WHERE "Adresses"."Author_ID"='X'

UNION

SELECT TO_NUMBER(NULL) AS "Author_ID", TO_CHAR(NULL) AS "Author_FirstName", TO_CHAR(NULL) AS "Author_LastName", 
       TO_CHAR(NULL) AS "Street_Coord", "Cities"."City_Name"
FROM "Cities"
WHERE "Cities"."Author_ID"='X'

Резултат R1:

ID_AUTHOR | AUTHOR_FirstName | AUTHOR_LastName | Street_Coord   | City_Name       |
----------------------------------------------------------------------------------
X         |James             | Conor           | NULL           | NULL            |
----------------------------------------------------------------------------------
X         |NULL              | NULL            | 1245 rich st   | NULL            |
----------------------------------------------------------------------------------
X         |NULL              | NULL            | 154 music st   | NULL            |
----------------------------------------------------------------------------------
X         |NULL              | NULL            | NULL           | Madrid          |
----------------------------------------------------------------------------------
X         |NULL              | NULL            | NULL           | Barcelona       |
----------------------------------------------------------------------------------

Резултат R2: Искам да ми помогнете да получите този резултат, моля:

ID_AUTHOR | AUTHOR_FirstName | AUTHOR_LastName | Street_Coord   | City_Name       |
----------------------------------------------------------------------------------
X         |James             | Conor           | 1245 rich st   | Madrid          |
----------------------------------------------------------------------------------
X         |James             | Conor           | 154 music st   | Barcelona       |
----------------------------------------------------------------------------------

Много благодаря, Walloud


person Walloud    schedule 23.05.2013    source източник
comment
Сигурни ли сте, че не искате JOIN вместо UNION?   -  person eaolson    schedule 23.05.2013
comment
Хей, eaolson, обединяването на 11 маси се срина! ORA-01652: не може да се разшири временен сегмент с 128 в таблично пространство TEMP 01652. 00000 - не може да се разшири временен сегмент с %s в таблично пространство %s *Причина: Неуспешно разпределяне на екстент от необходимия брой блокове за временен сегмент в посочено таблично пространство. *Действие: Използвайте израза ALTER TABLESPACE ADD DATAFILE, за да добавите един или повече файлове към посоченото таблично пространство.   -  person Walloud    schedule 23.05.2013
comment
Тази грешка звучи така, сякаш трябва да разширите размера на табличното си пространство TEMP. stackoverflow.com/questions/11839576/   -  person eaolson    schedule 24.05.2013


Отговори (2)


Първата мисъл е, че наистина искате да се присъедините към масите. Нещо като:

SELECT "Author"."Author_ID", "Author"."Author_FirstName", "Author.Author_LastName",
       "Adresses"."Street_Coord", "Cities"."City_Name"
FROM "Author" join
     "Adresses"
     on Author.Author_id = Adresses.Author_id join
     Cities
     on Author.Author_id = Cities.Author_id 
WHERE "Author"."Author_ID"='X';

Това обаче ще върне декартово произведение на стойностите, което е 4 реда, а не 2 реда. Изглежда, че целта е да се "подравнят" различните таблици. В такъв случай тази заявка се доближава до това, което искате:

SELECT "Author"."Author_ID", "Author"."Author_FirstName", "Author.Author_LastName",
       "Adresses"."Street_Coord", "Cities"."City_Name"
FROM "Author" join
     (select a.*, rownum as seqnum from "Adresses" a
     ) Adresses
     on Author.Author_id = Adresses.Author_id join
     (select c.*, rownum as seqnum from Cities c
     ) Cities
     on Author.Author_id = Cities.Author_id and addresses.seqnum = cities.seqnum
WHERE "Author"."Author_ID"='X';

Основният проблем с този подход е, че SQL таблиците по своята същност не са подредени. Имате нужда от колона, по която да ги подредите, за да може заявката да работи гарантирано. Например, ако имате автоматично увеличаващ се идентификатор в таблицата, тогава всяка подзаявка може да order by id.

person Gordon Linoff    schedule 23.05.2013
comment
Подозирам, че първият ви отговор е това, което Walloud възнамерява, но тогава Cities се нуждае от address_id, а не от author_id. - person eaolson; 23.05.2013
comment
@eaolson . . . OP е доста ясно какво съдържат таблиците. Структурата определено е необичайна. Предполагам, че това е нещо като редове във формуляр с различни колони. - person Gordon Linoff; 23.05.2013
comment
Хей, момчета, в реалния свят имам 11 маси! Когато използвах JOIN на 11 таблици, Oracle се срина поради големия брой върнати записи, затова използвам UNION. Трябва да намеря решение само с UNION. Благодаря отново ! - person Walloud; 23.05.2013
comment
Това няма смисъл. Това са две различни операции. JOIN основно ще ви даде допълнителни колони, UNION ще ви даде повече редове. Все едно да питате как да завъртите колата, но не можете да използвате волана, така че искате да знаете как да го направите само с педала на газта. - person eaolson; 24.05.2013
comment
@Walloud . . . Предполагам, че Oracle се е сринал, защото съединенията не са били настроени правилно. Работата с 11 таблици не би трябвало да е проблем за Oracle. - person Gordon Linoff; 24.05.2013

Вие не искате да направите UNION, а искате да направите JOIN:

SELECT "Author"."Author_ID", "Author"."Author_FirstName", "Author.Author_LastName", "Adresses"."Street_Coord", "Cities"."City_Name"
 FROM "Author"
 INNER JOIN "Adresses" ON "Author"."Author_ID"="Adresses"."Author_ID"
 INNER JOIN "Cities" ON "Author"."Author_ID"="Cities"."Author_ID"
 WHERE "Author"."Author_ID"='X'

Не го тествах, може да съдържа правописни грешки...

Освен това ще трябва да имате допълнителна колона за свързване между „Адреси“ и „Градове“, за да съпоставите „1245 rich st“ с „Madrid“ и „154 music st“ и „Barcelona“. Нещо като "City_ID". След това го добавяте в клаузата INNER JOIN ... ON:

INNER JOIN "Cities" ON "Adresses"."City_ID"="Cities"."City_ID" AND "Author"."Author_ID"="Cities"."Author_ID"
person Eric Citaire    schedule 23.05.2013
comment
Хей, момчета, в реалния свят имам 11 маси! Когато използвах JOIN на 11 таблици, Oracle се срина поради големия брой върнати записи, затова използвам UNION. Трябва да намеря решение само с UNION. Благодаря отново ! - person Walloud; 23.05.2013
comment
Е, тогава вероятно трябва да изпълните множество заявки. Във вашия пример можете да изпълните заявка за информация за автора, като име и фамилия, и отделна заявка за адреси и градове. Има повече смисъл и ще извлечете по-малко данни, отколкото с една-единствена голяма дебела заявка. - person Eric Citaire; 24.05.2013
comment
хей Walloud, момчетата тук са прави, трябва да използвате оператора JOIN вместо оператора UNION. ако получавате проблема ORA-01652, опитайте да отстраните грешките, първо опитайте да обедините 2 таблици и всеки път се опитайте да добавите друга таблица към вашата заявка и се опитайте да разберете кои таблици карат заявката да хвърля изключение (ORA- 01652), след като го разберете, опитайте се да го оптимизирате, като добавите индекси (например на author_id в целевата таблица) - person planben; 18.07.2013