group_concat в двух разных таблицах дает дублированный результат во второй таблице - PullRequest
1 голос
/ 07 марта 2012

рассматривают три объекта как студента, курс, предмет. Ниже приведены ассоциации -

student has_many courses,
student has_many subjects.

Теперь я хочу получить записи о студентах с именами предметов и курсов, используя mysql group_concat, левое соединение на курсах, левое соединениепо предметам и group_by student_id.

Проблема в том, что group_concat('subjects.name') as subject_names дает мне повторяющиеся записи предметов, но group_concat('students.name') as student_names дает уникальные имена.

Почему ??

Ответы [ 3 ]

9 голосов
/ 07 марта 2012

2 левых соединения - это умножение строк на декартово произведение дочерних рядов на студента

Пример

  • Студент 1 имеет 3 курса и 2 предмета
  • Генерирует 6 строк для студента 1
  • Дает по одному course значению на предмет = каждый курс повторяется дважды
  • Дает по одному subject значению за курс = каждый предмет повторяется трижды

Исправить:

Вариант 1: Использовать GROUP_CONCAT(DISTINCT ...) согласно Документам MySQL

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

Вариант 2: Используйте производную таблицу UNION ALL +

SELECT
    Student, MAX(CourseConcat), MAX(SubjectConcat)
FROM
    (
    -- 2 separate SELECTs here
    .. student LEFT JOIN course ...
    UNION ALL
    .. student LEFT JOIN subjects...
    ) T
GROUP BY
   Student

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

0 голосов
/ 15 февраля 2015

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

Решение GROUP_CONCAT(DISTINCT ...), как указал gbn, прекрасно, пока вы на самом деле не получите несколько одинаковых значений или почти равны, как а и .

Я исключил ключевое слово из запроса и решил проблему с PHP. Если вам нужно только отличить á от простого array_unique, то добьетесь цели.

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

$values = array( 'Value1','Value1','Value2','Value2','Value2','Value2' );

Теперь как-то различай, сколько дубликатов ты имеешь ввиду. Я сделал следующее:

$x=0;
$first = reset($values);
while($first === $values[$x]) $x++;

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

foreach($values as $k => $v){
       if($k%$x !== 0) unset($values[$k]);
}

Вот и все. Печать значений $ сейчас даст вам:

Array
(
    [0] => Value1
    [2] => Value2
    [4] => Value2
)
0 голосов
/ 07 марта 2012

Следуя вашей логике, group_concat('subjects.name') as subject_names дает вам повторяющиеся записи, поскольку, возможно, для каждого студента имеется более 1 предмета, поэтому вы получаете дубликат записи для каждой записи студента в таблице subject, тогда как group_concat('students.name') as student_names (Iпредположить) имеет 1 запись на одного студента.

...