MYSQL - GROUP_CONCAT И FIND_IN_SET смешивают значения/порядок?

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

Это код SQL:

SELECT 
    GROUP_CONCAT(DISTINCT options.option_name SEPARATOR ',') AS selected,
    user_login.firstname, user_login.lastname,
    event.event_title
FROM
    options, user_login, event, votes, questions
WHERE
    event.id = ? AND questions.Event_id = event.id 
    AND votes.user_id = user_login.id AND votes.question_id = questions.id 
    AND FIND_IN_SET(options.id, selected)

СГРУППИРОВАТЬ ПО user_login.id ПОРЯДОК ПО user_login.class

Примерным значением голосов может быть:

id |  event_id  | question_id  |  selected   |  user_id
25       14           42          52,46,41         1
26       14           43             68            1

Варианты такие:

id |  option_name   | question_id
 40        Project A          42
 41        Project B          42
 46        Project C          42     
 52        Project D          42
 67        Hello              43
 68        Bye                43

Вопросы такие:

id  |  question_name  | event_id
42     Project Number       14
43     Greeting             14

Событие похоже на:

id  |  title
14     Project Testing

И вывод данного кода:

selected                            |  event_title
Project C, Bye, ProjectD, Project B      Test

Как я могу сохранить первоначальный порядок, чтобы он выводил меня: Проект D, Проект C, Проект B, До свидания?


person Buffer Overflow    schedule 26.07.2014    source источник
comment
а можно реальные данные? как данные, которые будут соответствовать желаемому результату?   -  person John Ruddell    schedule 26.07.2014
comment
Я добавил некоторые реальные данные   -  person Buffer Overflow    schedule 26.07.2014
comment
Плохие привычки: использование JOIN в старом стиле — старый стиль разделенного запятыми списка таблиц был заменен на правильный синтаксис ANSI JOIN в Стандарт ANSI-92 SQL (более 20 лет назад), и его использование не рекомендуется.   -  person marc_s    schedule 18.07.2015


Ответы (1)


что-то вроде этого будет работать? в основном вы говорите порядок значений полей и делаете их похожими на «52», «46» и т. д.

SELECT 
    GROUP_CONCAT(DISTINCT options.option_name 
                 ORDER BY FIELD( options.id, 
                                 concat('"', 
                                        replace(selected, ',', '","'),
                                        '"') 
                               ) 
                 SEPARATOR ','
                ) AS selected,
    user_login.firstname, user_login.lastname,
    event.event_title
FROM options, user_login, event, votes, questions
WHERE event.id = ? AND questions.Event_id = event.id 
  AND votes.user_id = user_login.id AND votes.question_id = questions.id 
  AND FIND_IN_SET(options.id, selected)
GROUP BY user_login.id
ORDER BY user_login.class

ИЗМЕНИТЬ:

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

SET @order_field := (
    SELECT 
        group_concat(
            CONCAT('"', replace(selected, ',', '","'), '"')
        ) 
    FROM votes);

тогда запрос будет намного легче читать...

SELECT 
    GROUP_CONCAT(DISTINCT options.option_name 
                 ORDER BY FIELD( options.id, @order_field) 
                 SEPARATOR ','
                ) AS selected,
    user_login.firstname, user_login.lastname,
    event.event_title
FROM options, user_login, event, votes, questions
WHERE event.id = ? AND questions.Event_id = event.id 
  AND votes.user_id = user_login.id AND votes.question_id = questions.id 
  AND FIND_IN_SET(options.id, selected)
GROUP BY user_login.id
ORDER BY user_login.class
person John Ruddell    schedule 26.07.2014
comment
Это каким-то образом имеет тот же результат, что и мой запрос: - person Buffer Overflow; 26.07.2014
comment
@BufferOverflow вы пробовали это с переменной? работал на моем конце - person John Ruddell; 26.07.2014
comment
Мне пришлось заменить o.id на идентификатор параметров, а затем я попробовал запрос, но результат такой же, как упоминалось ранее. - person Buffer Overflow; 26.07.2014
comment
@BufferOverflow хм, не знаю, почему на вашей стороне это отличается от моего. я получал правильный результат. может быть, это как-то связано с вашей таблицей пользователей? - person John Ruddell; 26.07.2014
comment
@BufferOverflow попробуйте записать их вручную и посмотрите, сработает ли это.. aka ORDER BY FIELD( orders.id, 52,46,41,68) - person John Ruddell; 26.07.2014
comment
Он работал с некоторыми изменениями: ORDER BY votes.id, FIELD [...] replace(votes.selected[...]. Спасибо! - person Buffer Overflow; 28.07.2014
comment
@BufferOverflow был довольно близок! Рад, что смог помочь :) - person John Ruddell; 28.07.2014