2014-12-06 3 views
0

У меня есть две таблицыMysql присоединиться табличный результат в один ряд

PRJ

id | ptitle 
1 | prj111 
2 | prj222 

prjflow

id | pid | paction | pactiontxt 
1 | 1 | 1 |  man1 
2 | 1 | 1 |  man2 
3 | 1 | 2 |  woman1 
4 | 1 | 1 |  man3 

я хочу этот вывод:

выход

ptitle | men  | women 
prj111 | man1,men3 | woman1 

я пишу этот запрос:

SELECT prj.ptitle 
    , GROUP_CONCAT(pflow1.pactiontxt) men 
    , GROUP_CONCAT(pflow2.pactiontxt) women 
    FROM prj 
    JOIN prjflow pflow1 
    ON prj.id = pflow1.pid 
    AND pflow1.paction = 1 
    JOIN prjflow pflow2 
    ON prj.id = pflow2.pid 
    AND pflow2.paction = 2; 

но выход есть:

ptitle | men  | women 
prj111 | man1,men3 | woman1,woman1 

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

Большое спасибо и извините меня за плохой английский письменно

+0

Но почему, о почему? :-( – Strawberry

+1

И почему man2 отсутствует в результирующем наборе? – Strawberry

ответ

3

Просто используйте условную агрегацию:

SELECT prj.ptitle, 
     GROUP_CONCAT(CASE WHEN prjflow.paction = 1 THEN prjflow.pactiontext END ORDER BY prjflow.id) as men, 
     GROUP_CONCAT(CASE WHEN prjflow.paction = 2 THEN prjflow.pactiontext END ORDER BY prjflow.id) as women 
FROM prj JOIN 
    prjflow 
    ON prj.id = prjflow.pid 
GROUP BY prj.ptitle; 

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

Here - это скрипт SQL, демонстрирующий его.

Обратите внимание, что предлагаемый выход кажется несовместимым с входными данными. Это выводит:

ptitle | men   | women 
prj111 | man1,man2,men3 | woman1 

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

+0

Это был я, который ниспровергался. Я не собирался комментировать быть бесполезным. Я оставил комментарий, потому что я не хотел быть анонимным downvoter и хотел указать на ошибку.Но вы правы, проблема решается этим запросом. Я был не прав (первый раз КОГДА-ЛИБО! ;-)) Комментарий удален, ответьте на это. – GolezTrol

+0

спасибо. очень приятно и просто – Alireza

0

«Быстрое исправление» будет использовать distinct в group_concat агрегации:

SELECT 
    prj.ptitle, 
    group_concat(distinct pflow1.pactiontxt) AS men, 
    group_concat(distinct pflow2.pactiontxt) AS women 
FROM prj 
JOIN prjflow AS pflow1 ON (prj.id = pflow1.pid AND pflow1.paction = 1) 
JOIN prjflow AS pflow2 ON (prj.id = pflow2.pid AND pflow2.paction = 2) 
GROUP BY 
    prj.ptitle -- Officially you'll need this as well, although MySQL is quite forgiving. 

Но запрос по-прежнему использует два соединения, и даже не сработает, если нет мужчин или нет женщин для конкретного проекта.

Чтобы решить эту проблему, вы можете написать запрос с помощью подзапросов. Таким образом, вам не понадобятся объединения distinct или group by, и запрос будет работать, когда в элементе нет мужчин или вообще нет женщин.

SELECT 
    prj.ptitle, 
    (SELECT group_concat(pflow1.pactiontxt) FROM prjflo pflow1 
    WHERE prj.id = pflow1.pid AND pflow1.paction = 1) AS men, 
    (SELECT group_concat(pflow2.pactiontxt) FROM prjflo pflow2 
    WHERE prj.id = pflow2.pid AND pflow2.paction = 2) AS women 
FROM prj 
+0

Нет лучшего способа? – Strawberry

+0

О, есть ;-) – Strawberry

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