SQL MariaDB получает данные из 7 таблиц, включая mm-таблицы, что приводит к слишком большому количеству нежелательных строк - PullRequest
0 голосов
/ 04 мая 2018

Я пытаюсь получить данные из 7 разных таблиц sql без получения слишком большого количества строк.

У меня есть следующий (простой) запрос, который извлекает данные из 7 разных таблиц:

SELECT h.name, h.address, h.zipcode, h.city, h.association, r.name_de, f.first_name, f.last_name, f.email, p.year, j.name
FROM `tx_gipdhotels_domain_model_hotel` AS h

JOIN `tx_gipdhotels_hotel_jobs_mm` AS hj ON h.uid = hj.uid_local
JOIN `tx_gipdhotels_domain_model_jobs` AS j ON j.uid = hj.uid_foreign
JOIN `tx_gipdhotels_hotel_participations_mm` AS hp ON h.uid = hp.uid_local
JOIN `tx_gipdhotels_domain_model_participations` AS p ON p.uid = hp.uid_foreign
JOIN `tx_gipdhotels_domain_model_region` AS r ON r.uid = h.region
JOIN `fe_users` AS f ON f.uid = h.feuser

Как видите, между таблицами существует два отношения "многие ко многим". Эти две таблицы не связаны (кроме как через таблицу h). Теперь проблема в том, что это приводит к получению строки для каждой возможной комбинации этих мм-таблиц.

Пример:

стол 1 отель

|-----------|------------|----------|----------|
|    uid    |    name    |   jobs   |   part   |
|...........|............|..........|..........|
|     1     |     ab     |     3    |     2    |
|           |            |          |          |

Таблица 2 рабочих мест

|-----------|------------|
|    uid    |    name    |
|...........|............|
|     1     |    tech    |
|     2     |     cs     |
|     3     |    perf    |
|           |            |

таблица 3 часть

|-----------|------------|
|    uid    |    name    |
|...........|............|
|     1     |    abcd    |
|     2     |    efgh    |
|           |            |

При такой комбинации (включая таблицы mm для hotel_jobs и hotel_part) я получу 6 строк только для одного отеля, и в каждом ряду только одно значение будет отличаться от другого ряда:

результат:

|-----------|------------|----------|----------|
|    uid    |    name    |   job    |   part   |
|...........|............|..........|..........|
|     1     |     ab     |   tech   |   abcd   |
|     1     |     ab     |   tech   |   defg   |
|     1     |     ab     |    cs    |   abcd   |
|     1     |     ab     |    cs    |   defg   |
|     1     |     ab     |   perf   |   abcd   |
|     1     |     ab     |   perf   |   defg   |
|           |            |          |          |

Было бы замечательно, если бы я мог получить эти данные в одну строку, как показано ниже:

желаемый результат:

|-----------|------------|--------------------|----------------|
|    uid    |    name    |         job        |      part      |
|...........|............|....................|................|
|     1     |     ab     |   tech, cs, perf   |   abcd, efgh   |
|           |            |                    |                |

Я не могу понять, как получить желаемый результат, он превосходит мой опыт и знания, поэтому я спрашиваю вас, знаете ли вы, как добиться этого с помощью одного запроса?

Я немного погуглил и нашел метод STUFF (), но он не поддерживается в MariaDB. В некотором вопросе здесь в стеке кто-то сделал что-то подобное с приведением, но я не очень хорошо понял это, и я не знал, как приспособить это к моей проблеме ...

Я использую MariaDB, и запрос будет сделан из php. Нет способа изменить структуру данных таблиц.

Любая помощь и объяснения будут с благодарностью.

Ответы [ 2 ]

0 голосов
/ 04 мая 2018

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

SELECT 
    h.name, 
    h.address,
    h.zipcode,
    h.city,
    h.association,
    GROUP_CONCAT(DISTINCT p.year SEPARATOR ', '),
    GROUP_CONCAT(DISTINCT j.name SEPARATOR ', '),
    r.name_de,
    f.first_name,
    f.last_name,
    f.email,
    h.tstamp,
    h.crdate 
    FROM tx_gipleasedisturbhotels_domain_model_hotel AS h
    JOIN `tx_gipleasedisturbhotels_hotel_jobs_mm` AS hj 
    ON h.uid = hj.uid_local
    JOIN `tx_gipleasedisturbhotels_domain_model_jobs` AS j 
    ON j.uid = hj.uid_foreign
    JOIN `tx_gipleasedisturbhotels_hotel_participations_mm` AS hp 
    ON h.uid = hp.uid_local
    JOIN `tx_gipleasedisturbhotels_domain_model_participations` AS p 
    ON p.uid = hp.uid_foreign
    JOIN `tx_gipleasedisturbhotels_domain_model_region` AS r 
    ON r.uid = h.region
    JOIN `fe_users` AS f 
    ON f.uid = h.feuser
    GROUP BY h.name
    ORDER BY h.name ASC
0 голосов
/ 04 мая 2018

Благодаря @jarlh я нашел решение:

SELECT h.name, h.address, h.zipcode, h.city, h.association,
GROUP_CONCAT(DISTINCT p.year SEPARATOR ', '),
GROUP_CONCAT(DISTINCT j.name SEPARATOR ', '),
r.name_de, f.first_name, f.last_name, f.email, h.tstamp, h.crdate

FROM `tx_gipleasedisturbhotels_domain_model_hotel` AS h

JOIN `tx_gipleasedisturbhotels_hotel_jobs_mm` AS hj ON h.uid = hj.uid_local
JOIN `tx_gipleasedisturbhotels_domain_model_jobs` AS j ON j.uid = hj.uid_foreign
JOIN `tx_gipleasedisturbhotels_hotel_participations_mm` AS hp ON h.uid = hp.uid_local
JOIN `tx_gipleasedisturbhotels_domain_model_participations` AS p ON p.uid = hp.uid_foreign
JOIN `tx_gipleasedisturbhotels_domain_model_region` AS r ON r.uid = h.region
JOIN `fe_users` AS f ON f.uid = h.feuser

GROUP BY h.name
ORDER BY h.name ASC

Это комбинация GROUP_CONCAT и GROUP BY. Он должен быть сгруппирован по полю, которое вы хотите иметь только один раз. Чтобы получить все значения mm в одну ячейку, вам нужно использовать GROUP_CONCAT для этих полей в инструкции SELECT.

С этим запросом я получаю желаемый результат. Может быть, это будет полезно для кого-то еще. ;)

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