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 с options id и след това изпробвах заявката, но резултатът е същият като споменатия по-рано. - person Buffer Overflow; 26.07.2014
comment
@BufferOverflow хм не съм сигурен защо е различно от твоята страна от моята. получавах правилния резултат. може би има нещо общо с вашата таблица с потребители? - person John Ruddell; 26.07.2014
comment
@BufferOverflow опитайте да ги запишете ръчно и вижте дали това работи.. известен още като 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