Уникальное соединение: 2 первичных ключа в один столбец

У меня возникла проблема с работой с 3 таблицами «Клиент», «Покупка» и «Рабочий процесс».

CustomerID является первичным ключом для таблицы Customer и представляет собой 3-значный INT EG.. 123

PurchaseID — это первичный ключ для таблицы Purchase, представляющий собой 8-значный INT EG.. 12345678

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

WFID    EntityID        Type        Ref

771     123             Customer    1
772     12345678        Purchase    2
773     124             Customer    1
774     125             Customer    1
775     12345679        Purchase    2

Первичный ключ для этих двух таблиц смешивается с одним столбцом entityID, и это вызывает у меня большие трудности с присоединением. Мне удалось сделать это присоединение к оператору case после (ON Workflow.EntityID =), который выглядит следующим образом.

ON Workflow.EntityID =)
Case    when ref = 1 THEN customer.customerID
    When ref = 2 THEN purchase.purchaseID
END

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

Был ли у кого-нибудь другой опыт работы с соединениями такого типа, когда столбец сочетает в себе смесь двух первичных ключей из отдельных таблиц?

Я упускаю что-то очевидное?


person user1653447    schedule 18.02.2014    source источник
comment
Я предлагаю изменить схему рабочего процесса на WFID, CustomerID, PurchaseID, Type, Ref.   -  person Utku Yıldırım    schedule 18.02.2014


Ответы (2)


Подобное условие в join очень затрудняет оптимизацию запроса. Попробуйте написать это как два отдельных соединения:

from workflow wf left outer join
     customer c
     on c.customerID = wf.EntityID and wf.ref = 1 left outer join
     purchase p
     on p.purchaseID = wf.EntityID and wf.ref = 2

Движок может гораздо лучше оптимизировать их.

person Gordon Linoff    schedule 18.02.2014
comment
Спасибо. Выглядит намного стабильнее, чем то, что у меня было раньше - person user1653447; 19.02.2014

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

--query--
where ref = 1 and Workflow.EntityID = customer.customerID
union all
--query--
where ref = 2 and Workflow.EntityID = purchase.purchaseID
person Dumitrescu Bogdan    schedule 18.02.2014
comment
UNION - это то, что я пробовал, но поскольку у меня есть несколько экземпляров в таблице рабочего процесса, и они никоим образом не уникальны, я получал дубликаты при составлении отчетов. Спасибо - person user1653447; 19.02.2014
comment
UNION даст вам те же результаты, что и 2 объединения, но с меньшим объемом памяти и, как правило, более высокой скоростью. Также он сохранит тот же набор результатов, что и исходный запрос. - person Dumitrescu Bogdan; 19.02.2014