MySQL Объединения: выбор таблицы для объединения на основе данных исходной таблицы - PullRequest
1 голос
/ 22 февраля 2020

Я нахожу этот запрос немного сложным для объяснения; возможно, есть какая-то краткая формулировка, с которой я не знаком.

TL / DR:

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

У меня есть таблица events. Каждое событие относится к одному из четырех topics; Исходные данные были только для одного topic, поэтому было простое соотношение таблиц 1: 1.

Но теперь клиент хочет расширить события до четырех разных тем;

Итак:


Возможные темы (у каждой своя таблица):

holidays | cruises | recruitment | fundays 

Примеры:

holidays таблица

    id     | holiday_name    | other data....
------------------------------------------------
    1      | basic holiday   | ..etc..
    2      | alpaca training | ..etc..  

А

fundays таблица

    id     | funday_title    | other data....
------------------------------------------------
    1      | balloons!       | ..etc..
    2      | seaweed fun!    | ..etc..  

Основным источником данных событий является таблица событий;

Таблица событий

event_id | reference_id | topic_type (ENUM) | event_name | other data.....
--------------------------------------------------------------
    1    |       1      |      hol          |  something |  ....
    2    |       4      |      cruise       |  some name |  ....
    3    |       1      |      funday       |   horses!  |  ....
    4    |       2      |      hol          |  whatever  |  ....

Итак, у каждого события есть таблица ссылок (topic_type) и идентификатор ссылки (reference_id) в этой таблице.

Я сейчас нахожусь в позиция, где я хочу получить название holidays / cruises / recruitment / fundays, относящееся к каждому событию . У меня есть идентификатор события, поэтому SQL будет:

SELECT event_name, etc... FROM events WHERE event_id = 1 

Но я также хочу получить имя топи c в том же запросе;

Я пытался что-то вроде этого Q & A :

SELECT events.event_name, other_table.
FROM events 
CASE 
LEFT JOIN holidays other_table ON events.topic_type = 'hol' AND events.reference_id = other_table.id
WHERE events.event_id = 1

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

Я ожидаю, что на выходе будут ссылки на недоступные таблицы; если я использую CASE для выбора таблиц для JOIN на основе критериев столбцов, то я предполагаю, что SELECT всегда будет ссылаться на 3 недействительные ссылки на таблицы, поэтому возникнут проблемы.


Я бы хотел, чтобы результат был:

SELECT events.event_name, events.event_id, other_table.____ as topic_name ....

, чтобы результат SQL мог быть:

Event_id = 1

  event_id | event_name | topic_name
 ------------------------------------------------------------
      1    |  something | basic holiday

Event_id = 2

   event_id | event_name | topic_name
------------------------------------------------------------
       2    | some name  | cruise Holiday title no.4

Event_id = 3

  event_id | event_name | topic_name
 ------------------------------------------------------------
      3    |   horses!  |  balloons!
  • Is это возможно?
  • Как это можно сделать?

Я смотрел здесь:

Но, похоже, что все это либо не может быть сделано, либо их места находятся в разных столбцах одной таблицы

Ответы [ 3 ]

1 голос
/ 22 февраля 2020

Требуется несколько left join с, в зависимости от типа. Я думаю что-то вроде этого:

SELECT e.*,
       COALESCE(h.name, f.name, c.name, r.name) as name
FROM events e LEFT JOIN
     holidays h
     on h.id = e.reference_id AND
        e.topic_type = 'holiday' LEFT JOIN
     fundays f
     on f.id = e.reference_id AND
        e.topic_type = 'funday' LEFT JOIN
     cruises c
     on c.id = e.reference_id AND
        e.topic_type = 'cruise' LEFT JOIN
     recruitment r
     on f.id = e.reference_id AND
        e.topic_type = 'recruitment'    
WHERE e.event_id = 1 
0 голосов
/ 22 февраля 2020

Рассмотрим также этот подход: укажите и объедините с подзапросом, CTE или даже представлением, которое содержит объединение данных из всех таблиц. Например:

SELECT e.*,
       t.name
FROM events e INNER JOIN
    (
      SELECT id, 'holiday' as type, name FROM Holidays
      UNION ALL
      SELECT id, 'funday' as type, name FROM Fundays
      UNION ALL
      SELECT id, 'cruise' as type, name FROM Cruises
      UNION ALL
      SELECT id, 'recruitment' as type, name FROM Recruitments
    ) t
  ON
      t.id = e.reference_id AND
      t.type = e.topic_type

Лично мне нравится избегать использования функций всякий раз, когда я могу, так как они имеют тенденцию отрицательно влиять на производительность.

0 голосов
/ 22 февраля 2020
SELECT m.field,
       COALESCE(s1.field, s2.field, s3.field, s4.field) AS field,
       ...
FROM main_table m
LEFT JOIN slave1_table s1 ON ...
LEFT JOIN slave2_table s2 ON ...
LEFT JOIN slave3_table s3 ON ...
LEFT JOIN slave4_table s4 ON ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...