SQL - Как транспонировать?

У меня есть что-то подобное следующей таблице:

================================================
| Id | UserId | FieldName     | FieldValue     |
=====+========+===============+================|
| 1  | 100    | Username      | John Doe       |
|----+--------+---------------+----------------|
| 2  | 100    | Password      | pass123!       |
|----+--------+---------------+----------------|
| 3  | 102    | Username      | Jane           |
|----+--------+---------------+----------------|
| 4  | 102    | Password      | $ecret         |
|----+--------+---------------+----------------|
| 5  | 102    | Email Address | jane@email.com |
------------------------------------------------

Мне нужен запрос, который даст мне результат как это:

==================================================
| UserId | Username  | Password | Email Address  |
=========+===========+===========================|
| 100    | John Doe  | pass123! |                |
|--------+-----------+----------+----------------|
| 102    | Jane      | $ecret   | jane@email.com |
|--------+-----------+----------+----------------|

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

Существует ли способ сделать это в SQL?

20
задан OMG Ponies 3 August 2010 в 01:18
поделиться

2 ответа

MySQL не поддерживает синтаксис ANSI PIVOT/UNPIVOT, поэтому вам придется использовать:

  SELECT t.userid
         MAX(CASE WHEN t.fieldname = 'Username' THEN t.fieldvalue ELSE NULL END) AS Username,
         MAX(CASE WHEN t.fieldname = 'Password' THEN t.fieldvalue ELSE NULL END) AS Password,
         MAX(CASE WHEN t.fieldname = 'Email Address' THEN t.fieldvalue ELSE NULL END) AS Email
    FROM TABLE t
GROUP BY t.userid

Как вы видите, операторы CASE должны быть определены для каждого значения. Чтобы сделать это динамическим, вам нужно использовать синтаксис MySQL's Prepared Statement (динамический SQL).

41
ответ дан 29 November 2019 в 23:44
поделиться

Можно использовать GROUP_CONCAT

(не проверено)

SELECT UserId, 
GROUP_CONCAT( if( fieldname = 'Username', fieldvalue, NULL ) ) AS 'Username', 
GROUP_CONCAT( if( fieldname = 'Password', fieldvalue, NULL ) ) AS 'Password', 
GROUP_CONCAT( if( fieldname = 'Email Address', fieldvalue, NULL ) ) AS 'Email Address', 
FROM table  
GROUP BY UserId
1
ответ дан 29 November 2019 в 23:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: