SQL Присоединяйтесь с предложением ИЛИ - PullRequest
0 голосов
/ 21 февраля 2020

Допустим, у нас есть следующий запрос

select
     *
from
     table_1 as a
left join
     table_2 as b
     on
          a.[id_1] = b.[emp_id] OR
          a.[id_1] = b.[worker_id]

Чем этот запрос отличается от приведенного ниже:

    select
         *
    from
         table_1 as a
    left join
         table_2 as b
         on
              a.[id_1] = b.[emp_id] 

union

    select
         *
    from
         table_1 as a
    left join
         table_2 as b
         on
              a.[id_1] = b.[worker_id]

Не являются ли оба запроса синонимами в отношении результатов go? Запрос с объединением выполняется намного быстрее, но я получаю другое количество записей, поэтому я спрашиваю.

Edit # 1

Нет индексов, и я не могу добавлять их.

Выполнение верхнего запроса занимает 20 минут. Нижний запрос выполняется 2 минуты.

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

39 758 записей возвращаются в верхнем запросе. Приблизительно 78 000 записей возвращаются за секунду.

Использование OR вместо IN, потому что именно так кто-то разработал хранимую процедуру. Я просто разбираю это, чтобы попытаться настроить что-то еще в хранимой процедуре.

Edit # 2:

Я создаю #temp таблицы и добавляю индексы в те, как решение. Прежде чем включать индексы, мне нужно убедиться, что я повторяю одинаковое количество записей.

** Правка № 3: **

Если вы хотите воспроизвести то, что я делаю, вот пример:

drop table #temp;
go

drop table #temp_2;
go
-----------------------------------

select
    1 as [id],
    cast('good' as varchar(255)) as [status]
into
    #temp;

go

insert into #temp(id,[status]) values
(2, 'bad'), (3, 'great'), (4, 'average');

go
------------------------------------------

select
    1 as [id],
    cast('good' as varchar(255)) as [status]
into
    #temp_2;
go

insert into #temp_2(id, [status]) values
(2, 'average'), (5, 'average'), (6, 'average');

go
-------------------------------------------------
select
    a.*,
    b.*
from
    #temp as a
left join
    #temp_2 as b
    on
        a.[id] = b.[id];

go

select
    a.*,
    b.*
from
    #temp as a
left join
    #temp_2 as b
    on
        a.[status] = b.[status];

go

select
    a.*,
    b.*
from
    #temp as a
left join
    #temp_2 as b
    on
        a.[id] = b.[id] OR
        a.[status] = b.[status];

go

Если вы посмотрите на самый последний запрос, запись в обеих таблицах, где ID = 1, вы заметите, что есть совпадение как по значению ID, так и по состоянию; однако возвращается только 1 запись.

Ответы [ 2 ]

5 голосов
/ 21 февраля 2020

Отвечая на ваш вопрос: «Разве оба запроса не являются синонимами в отношении результатов go?»
Нет.
Оба ваших объединения являются левыми, поэтому вам нужно подумать о 3 сценариях:
1. Существуют строки в обеих правых таблицах -> будут создаваться одинаковые записи
2. Существуют строки только в одной правой таблице -> Объединение создаст две или более строки с одной строкой значений NULL для правой таблицы и совпадением строк из других правильный стол Pure JOIN не будет создавать строки с NULL.
3. строк в обеих правых таблицах не существует -> одинаковые результаты (2 строки объединены различными)

0 голосов
/ 21 февраля 2020

Я понял, что не так, см. Редактировать # 3 , в моем вопросе, чтобы повторить мои результаты.

Старый образ мышления:

Если я присоединюсь, используя предложение ИЛИ, будет проверка, чтобы убедиться, что что-то соответствует по первым критериям, а затем он попытается соответствовать по вторым критериям.

Новый способ мышления:

Если я присоединюсь, используя предложение ИЛИ, будет проверка, чтобы убедиться, что что-то соответствует по первым критериям. Если совпадения не найдено, он применит второй критерий.

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