2016-12-07 3 views
0

Я пытаюсь получить следующий запрос, чтобы вернуть правильную информацию, но он возвращает различное количество значений для полей из одной таблицы.MYSQL/PHP: запрос с несколькими объединениями

Моя схема данных 3 таблицы:

airlines 
id|descript|userid 

travelers 
id|airid|ftrav|ltrav|active 

travair 
id|travid|airid 

Вот запрос:

SELECT a.id as `aid`,a.descript,userid, 
    group_concat(t.id) as `tids`, 
    group_concat(t.ftrav) as `ftravs`, 
    group_concat(IFNULL(t.ltrav,'')) as `ltravs`, 
    group_concat(t.active) as `tactives`, 
    ta.airid 
    FROM airlines `a` 
    LEFT JOIN travair `ta` 
    ON a.id = ta.airid 
    LEFT JOIN travelers `t` 
    ON ta.travid = t.id 
    WHERE a.userid='$userid' 
    GROUP BY a.id 

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

Однако поля group_concat имеют в них различное количество значений. В фактической таблице я в значительной степени устранил недостающие значения, чтобы не учитывать различия в количестве элементов. Кажется, что-то не так с запросом.

Может ли кто-нибудь указать мою ошибку? С этим боролись пару дней.

+0

необходимо увидеть некоторые данные, чтобы это исправить –

+0

Каков ваш прецедент для такой конкатенации? Это не похоже на то, что вы делаете какую-либо реальную агрегацию здесь, и вам все равно придется разложить полученное значение строк в приложении, чтобы работать с отдельными значениями. Почему бы просто не зачитать полный набор записей и агрегат в приложении в соответствующую структуру данных? –

+0

В фактических данных для одной конкретной авиакомпании, я получаю 57 путешественников, но только 33 ftrav значения. Насколько я знаю, все эти траверлериды связаны с значениями ftrav и ltrav. Я пытался разобрать их по одному, чтобы выяснить, что происходит, но есть тысячи путешественников и много авиакомпаний. – user6631314

ответ

0

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

Что вы можете сделать? Быстрый и грязный раствор использовать distinct ключевое слово:

SELECT a.id as `aid`,a.descript,userid, 
     group_concat(distinct t.id) as `tids`, 
     group_concat(distinct t.ftrav) as `ftravs`, 
     group_concat(distinct coalesce(t.ltrav, '')) as `ltravs`, 
     group_concat(distinct t.active) as `tactives` 

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

Примечание: Возможно, что distinct не будет работать в вашем случае, если вам нужно, чтобы все списки имели одинаковую длину.

+0

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

+0

Как бы я предварительно агрегировал? Это отдельный запрос? – user6631314

0

GROUP_CONCAT, как и большинство функций агрегации, игнорирует значения NULL. Поскольку вы используете левые соединения, любые GROUP_CONCAT s в полях из таблиц с правой стороны этих объединений могут иметь нулевые значения для некоторых строк результата для предварительной агрегации.

Редактировать: Если вы хотите синтезировать «результаты» для отсутствия данных, вы можете агрегировать рассчитанные значения; вы на самом деле уже сделали один раз с этим немного ...

group_concat(IFNULL(t.ltrav,'')) as `ltravs` 

.... вы можете просто взять его немного дальше (сделать отсутствие этих данных немного более очевидным) с чем-то вроде этого:

GROUP_CONCAT(IFNULL(theField, '[Not Recorded]')) AS theList 
+0

Можете ли вы предложить способ получения списков для каждого заполняемого поля путешественника (т. Е. Иметь элемент, если необходимо, - для каждого путешественника)? – user6631314

+0

@ user6631314 см. Редактировать – Uueerdo

Смежные вопросы