Функции SQL - UNION и NULL.Что лучше? - PullRequest
0 голосов
/ 04 января 2019

У меня есть три таблицы: ACCT, PERS, ORG.Каждый ACCT принадлежит либо PERS, либо ORG.Таблицы PERS и ORG очень похожи, как и все их дочерние таблицы, но все данные PERS и ORG разделены.

Я пишу запрос, чтобы получить данные PERS и ORG для каждой учетной записи в ACCT, и мне любопытно, каков наилучший способ объединения информации.Должен ли я использовать серию левых объединений и NULL-функций для заполнения пробелов или я должен написать запросы отдельно и использовать UNION для объединения?

Я уже написал отдельные запросы для PERS ACCT и еще один для ORGACCT и планируем использовать UNION.Мой вопрос больше касается наилучшей практики в будущем.

Я ожидаю, что оба результата дадут мне желаемые результаты, но я хочу найти наиболее эффективный метод как во время разработки, так и во время выполнения.

РЕДАКТИРОВАТЬ: Пример данных таблицы

Таблица ACCT:

+---------+---------+--------------+-------------+
| ACCTNBR | ACCTTYP | OWNERPERSNBR | OWNERORGNBR |
+---------+---------+--------------+-------------+
|  555001 | abc     |         3010 |             |
|  555002 | abc     |              |        2255 |
|  555003 | tre     |         5125 |             |
|  555004 | tre     |         4485 |             |
|  555005 | dsa     |              |        6785 |
+---------+---------+--------------+-------------+

Таблица PERS:

+---------+--------------+---------------+----------+-------+
| PERSNBR |    PHONE     |    STREET     |   CITY   | STATE |
+---------+--------------+---------------+----------+-------+
|    3010 | 555-555-5555 | 1234 Main St  | New York | NY    |
|    5125 | 555-555-5555 | 1234 State St | New York | NY    |
|    4485 | 555-555-5555 | 6542 Vine St  | New York | NY    |
+---------+--------------+---------------+----------+-------+

Таблица ORG:

+--------+--------------+--------------+----------+-------+
| ORGNBR |    PHONE     |    STREET    |   CITY   | STATE |
+--------+--------------+--------------+----------+-------+
|   2255 | 222-222-2222 | 1000 Main St | New York | NY    |
|   6785 | 333-333-3333 | 400 4th St   | New York | NY    |
+--------+--------------+--------------+----------+-------+

Желаемый выход:

+---------+---------+--------------+-------------+--------------+---------------+----------+-------+
| ACCTNBR | ACCTTYP | OWNERPERSNBR | OWNERORGNBR |    PHONE     |    STREET     |   CITY   | STATE |
+---------+---------+--------------+-------------+--------------+---------------+----------+-------+
|  555001 | abc     |         3010 |             | 555-555-5555 | 1234 Main St  | New York | NY    |
|  555002 | abc     |              |        2255 | 222-222-2222 | 1000 Main St  | New York | NY    |
|  555003 | tre     |         5125 |             | 555-555-5555 | 1234 State St | New York | NY    |
|  555004 | tre     |         4485 |             | 555-555-5555 | 6542 Vine St  | New York | NY    |
|  555005 | dsa     |              |        6785 | 333-333-3333 | 400 4th St    | New York | NY    |
+---------+---------+--------------+-------------+--------------+---------------+----------+-------+

Вариант запроса 1: написать 2 запроса и использовать UNION для их объединения:

select a.acctnbr, a.accttyp, a.ownerpersnbr, a.ownerorgnbr, p.phone, p.street, p.city, p.state
from acct a 
inner join pers p on p.persnbr = a.ownerpersnbr

UNION

select a.acctnbr, a.accttyp, a.ownerpersnbr, a.ownerorgnbr, o.phone, o.street, o.city, o.state
from acct a
inner join org o on o.orgnbr = a.ownerorgnbr 

Вариант 2: использовать NVL () или Coalesce для возврата одного набора данных:

SELECT a.acctnbr,
a.accttyp,
NVL(a.ownerpersnbr, a.ownerorgnbr) Owner,
NVL(p.phone, o.phone) Phone,
NVL(p.street, o.street) Street,
NVL(p.city, o.city) City,
NVL(p.state, o.state) State

FROM
acct a
LEFT JOIN pers p on p.persnbr = a.ownerpersnbr
LEFT JOIN org o on o.orgnbr = a.ownerorgnbr

Тамнамного больше полей в каждой из 3 таблиц, а также много других таблиц PERS и ORG в моем реальном запросе.Один способ лучше (быстрее, эффективнее), чем другой?

Ответы [ 2 ]

0 голосов
/ 04 января 2019

Я думаю, вы неправильно понимаете, что делает Союз против заявления о присоединении.Объединение берет записи из нескольких таблиц, обычно похожих или одинаковых по структуре, и объединяет их в один набор результатов.Он не предназначен для объединения нескольких разнородных таблиц.

Я вижу, что у вас есть две таблицы PERS и ORG с одними и теми же данными.В этом случае я предлагаю вам объединить эти две таблицы и затем присоединиться к ACCT, чтобы получить пример выходных данных.

В этом случае, чтобы получить выходные данные, как вы показали, вы захотите использовать Внешние объединения, чтобы не отбрасывать записи без совпадений.Это даст вам нулевые значения в некоторых местах, но в большинстве случаев это то, что вы хотите.Гораздо проще отфильтровать их позже.

Очень грубый пример кода.

SELECT a.*, b.* 
from Acct as a
FULL OUTER JOIN ( 
   Select * from PERS UNION Select * from ORG
      ) as b
ON a.ID = b.ID
0 голосов
/ 04 января 2019

Это зависит от того, что вы считаете «лучше».

Предполагая, что вы всегда захотите извлечь все строки из таблицы ACCT, я бы сказал, что нужно перейти к LEFT OUTER JOIN, и нетUNION.(При использовании UNION, а затем перейдите к варианту UNION ALL.)

РЕДАКТИРОВАТЬ : поскольку вы уже показали свои запросы, мои больше не требуются и не соответствуютваши структуры.Удаление этой части.

Почему LEFT JOIN?Потому что с UNION вам придется пройти через ACCT дважды, основываясь на «родительских» критериях (независимо от того, были ли они выполнены или выполнены по INNER JOIN критериям), в то время как с простым LEFT OUTER JOIN вы, вероятно, получите только один проход через ACCT.В обоих случаях доступ к строкам «родителей», скорее всего, будет осуществляться на основе первичных ключей.

Поскольку вы, вероятно, рассматриваете производительность, при поиске «лучше», как всегда: протестируйте свои запросы и посмотрите на выполнениепланы с адекватной и свежей статистикой базы данных, поскольку в зависимости от «разметки» данных (гистограммы и т. д.) «лучше» может быть чем-то совершенно другим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...