2013-05-23 2 views
0

Я делаю UNION между 3 таблицами. Чтобы поставить вас на изображение, одна таблица рассматривается как основная таблица, а две другие таблицы рассматриваются как подтаблицы. У двух подкатегорий всегда одинаковое количество записей для каждого случая. Поэтому я хотел сделать объединение между этими тремя таблицами, в этом объединении я хотел бы повторить информацию в столбце, взятом в основной таблице, и перечислить информацию в виде двух подклассов, где каждая строка в подкатегории 1 соответствует строке в подкатегории 2. Я не могу поместить реальный код по профессиональным причинам, так что вот простой пример, соответствующий моему реальному делу. Рассмотрим таблицу под названием Author (Author_ID, Author_FirstName, Author_LastName). Эта таблица будет нашей главной таблицей. Затем рассмотрим таблицу под названием «Адреса» (Adress_ID, Street_Coord, Author_ID), это будет наша подкатегория 1. Затем рассмотрим таблицу с названием «Города» (City_ID, City_Name, Author_ID). Наш автор X имеет 2 адреса в 2 городах. Когда я выполняю свой запрос, я получаю результат R1, который полностью логичен, но я хочу изменить свой запрос, чтобы получить результат R2. Не могли бы вы помочь мне изменить мой запрос, чтобы получить результат R2?Оптимизация запроса sql-соединения

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

+0

Вы уверены, что не хотите ОБЪЕДИНЯТЬ вместо СОЮЗА? – eaolson

+0

Hey eaolson, объединение 11 таблиц разбилось! ORA-01652: не удалось продлить временный сегмент на 128 в табличном пространстве TEMP 01652. 00000 - «невозможно продлить временный сегмент на% s в табличном пространстве% s» * Причина: Не удалось выделить объем необходимого количества блоков для - временной сегмент в указанном табличном пространстве. * Действие: Используйте инструкцию ALTER TABLESPACE ADD DATAFILE, чтобы добавить один или несколько файлов в указанное табличное пространство. – Walloud

+0

Эта ошибка звучит так, как будто вам нужно расширить размер табличного пространства TEMP. http://stackoverflow.com/questions/11839576/ora-01652-unable-to-extend-temp-segment-by-in-tablespace – eaolson

ответ

0

Сначала мы думали, что вы действительно хотите присоединиться к столам вместе. Что-то вроде:

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 являются по своей сути неупорядоченные. Для того, чтобы запрос гарантированно работал, вам нужна колонка, чтобы заказать их. Например, если у вас есть auto-incrementing id в таблице, то каждый подзапрос может быть на order by id.

+0

Я подозреваю, что ваш первый ответ - это то, что Walloud * намеревается *, но тогда Городам нужна address_id, а не author_id. – eaolson

+0

@eaolson. , , OP довольно ясно из того, что содержат таблицы. Структура определенно необычна. Я предполагаю, что это что-то вроде строк в форме с разными столбцами. –

+0

Эй, ребята, в реальном мире у меня 11 столов! Когда я использовал JOIN на 11 таблицах, Oracle разбился из-за большого количества возвращенных записей, поэтому я использую UNION. Я должен найти решение только с UNION. Еще раз спасибо ! – Walloud

0

Вы не хотите сделать 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 богатой ст» с «Мадридом» и «154 музыкой» и «Барселоной». Что-то вроде «City_ID». Затем вы добавляете его в позицию INNER JOIN ... ON:

INNER JOIN "Cities" ON "Adresses"."City_ID"="Cities"."City_ID" AND "Author"."Author_ID"="Cities"."Author_ID" 
+0

Эй, ребята, в реальном мире у меня 11 столов! Когда я использовал JOIN на 11 таблицах, Oracle разбился из-за большого количества возвращенных записей, поэтому я использую UNION. Я должен найти решение только с UNION. Еще раз спасибо ! – Walloud

+0

Ну, вы должны, вероятно, выполнить несколько запросов. В вашем примере вы можете выполнить запрос для информации об авторе, например, имя и фамилию, а также отдельный запрос для адресов и городов. Это имеет больший смысл, и вы получите меньше данных, чем с помощью одного большого толстого запроса. –

+0

эй Walloud, ребята здесь правы, вы должны использовать инструкцию JOIN вместо утверждения UNION. если вы получаете проблему ORA-01652, попробуйте «отладить» это, сначала попробуйте присоединиться к 2 таблицам и каждый раз пытайтесь добавить другую таблицу в свой запрос и попытаться понять, какие таблицы заставляют запрос генерировать исключение (ORA-01652), после того, как вы это поняли, попробуйте оптимизировать его, добавив индексы (например, в файл author_id в целевой таблице) – planben

Смежные вопросы