Один-ко-многим SQL SELECT в одну строку

У меня есть данные в двух таблицах.

Первая таблица имеет первичный ключ, называемый PKID

PKID  DATA
0    myData0
1    myData1
2    myData2

Вторая таблица имеет столбец PKID из таблицы 1 в качестве внешнего ключа

PKID_FROM_TABLE_1  U_DATA
       0          unique0
       0          unique1        
       0          unique2
       1          unique3
       1          unique4
       1          unique5
       2          unique6
       2          unique7
       2          unique8

Основной оператор SELECT, который я делаю сейчас, это

SELECT a.PKID, a.DATA, b.U_DATA
FROM table1 as a
INNER JOIN table2 as b
ON a.PKID = b.PKID_FROM_TABLE_1

Это создает таблицу, подобную этой:

PKID   DATA     U_DATA
 0   myData0    unique0
 0   myData0    unique1
 0   myData0    unique2
 1   myData1    unique3
 1   myData1    unique4
 1   myData1    unique5
 2   myData2    unique6
 2   myData2    unique7
 2   myData2    unique8

Мне бы хотелось, чтобы следующая таблица:

PKID   DATA    U_DATA1    U_DATA2    U_DATA3
 0     myData0 unique0    unidque1   unique2
 1     myData1 unique3    unidque4   unique5
 2     myData2 unique6    unidque7   unique8

Если это помогает, каждый PKID будет иметь ровно 3 записи в таблице2.

В MySQL возможно что-то подобное?

Ответы

Ответ 1

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

Этот подход использует коррелированные подзапросы. Каждый подзапрос использует предложение ORDER BY для сортировки связанных строк из таблицы2 и использует предложение LIMIT для извлечения 1-й, 2-й и 3-й строк.

SELECT a.PKID
     , a.DATA
     , (SELECT b1.U_DATA FROM table2 b1
         WHERE b1.PKID_FROM_TABLE_1 = a.PKID 
         ORDER BY b1.U_DATA LIMIT 0,1
       ) AS U_DATA1
     , (SELECT b2.U_DATA FROM table2 b2
         WHERE b2.PKID_FROM_TABLE_1 = a.PKID 
         ORDER BY b2.U_DATA LIMIT 1,1
       ) AS U_DATA2
     , (SELECT b3.U_DATA FROM table2 b3
         WHERE b3.PKID_FROM_TABLE_1 = a.PKID 
         ORDER BY b3.U_DATA LIMIT 2,1
       ) AS U_DATA3
  FROM table1 a
 ORDER BY a.PKID  

Followup

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

Нельзя сказать, что этот подход кричит для индекса:

ON table2 (PKID_FROM_TABLE_1, U_DATA)

-или, как минимум -

ON table2 (PKID_FROM_TABLE_1)

Вероятно, последний индекс уже существует, если имеется внешний ключ. Первый индекс позволит полностью выполнить запрос с индексных страниц ( "Использование индекса" ) без необходимости операции сортировки ( "Использование файлового набора" ).

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

Ответ 2

В зависимости от выпуска MySQL вы можете посмотреть GROUP_CONCAT