Oracle: проверьте, существуют ли строки в другой таблице - PullRequest
5 голосов
/ 16 декабря 2009

У меня есть запрос, объединяющий несколько таблиц и возвращающий довольно много столбцов.

Индексированный столбец другой таблицы ссылается на PK одной из этих объединенных таблиц. Теперь я хотел бы добавить в запрос еще один столбец, в котором указано, существует ли хотя бы одна строка с таким идентификатором в новой таблице.

Так что, если у меня есть одна из старых таблиц

ID
 1
 2
 3

и новый стол

REF_ID
1
1
1
3

тогда я бы хотел получить

ID   REF_EXISTS
 1            1
 2            0
 3            1

Я могу придумать несколько способов сделать это, но какой из них самый элегантный / эффективный?


EDIT Я проверил производительность запросов, предоставленных 50 000 записей в старой таблице, каждая вторая запись соответствует двум строкам в новой таблице, поэтому половина записей имеет REF_EXISTS = 1.

Я добавляю средние результаты в качестве комментариев к ответам на случай, если кому-то будет интересно. Спасибо всем!

Ответы [ 4 ]

7 голосов
/ 16 декабря 2009

Другой вариант:

select O.ID
    , case when N.ref_id is not null then 1 else 0 end as ref_exists
from old_table o
left outer join (select distinct ref_id from new_table) N
   on O.id = N.ref_id
4 голосов
/ 17 декабря 2009

Я бы:

select distinct ID,
       case when exists (select 1 from REF_TABLE where ID_TABLE.ID = REF_TABLE.REF_ID)
    then 1 else 0 end
    from ID_TABLE

Если у вас есть индексы на ПК и FK, вам не придется сканировать таблицы и искать индексы.

С уважением K

1 голос
/ 16 декабря 2009

A join может вернуть несколько строк для одного идентификатора, как это происходит для id=1 в данных примера. Вы можете ограничить его одной строкой на идентификатор группы:

SELECT 
    t1.id
,   COUNT(DISTINCT t2.ref_id) as REF_EXISTS
FROM TABLE_1 t1
LEFT JOIN TABLE_2 t2 ON t2.ref_id = t1.id
GROUP BY t1.id

group by обеспечивает наличие только одной строки для каждого идентификатора. И count(distinct t2.ref_id) будет 1, если строка найдена, и 0 в противном случае.

РЕДАКТИРОВАТЬ: Вы можете переписать его без group by, но я сомневаюсь, что это сделает вещи проще:

SELECT 
    t1.id
,   CASE WHEN EXISTS (
        SELECT * FROM TABLE_2 t2 WHERE t2.ref_id = t1.id)
        THEN 1 ELSE 0 END as REF_EXISTS
,   ....
FROM TABLE_1 t1
1 голос
/ 16 декабря 2009

Использование:

   SELECT DISTINCT t1.id,
          CASE WHEN t2.ref_id IS NULL THEN 0 ELSE 1 END AS REF_EXISTS
     FROM TABLE_1 t1
LEFT JOIN TABLE_2 t2 ON t2.ref_id = t1.id

Добавлено DISTINCT для обеспечения отображения только уникальных строк.

...