[英]MYSQL Subquery Rows as Columns in Main Query
在我們的數據庫中,我們有一個用戶表和其他數據的鍵值表。 我們一直在嘗試提出一個將兩者連接起來的查詢,將 kv 表中的鍵作為列標題,將值作為字段。
目前我們唯一的解決方案是將每個用戶的鍵值對GROUP_CONCAT
作為一列,然后在查詢輸出后解析它們——緩慢而糟糕......
這是一般設置:
User.db 表:
------------------------------
| uid | firstname | lastname |
------------------------------
| 01 | john | doe |
| 02 | jane | doe |
------------------------------
-----------------------------
| uid | question | answer |
-----------------------------
| 01 | question1 | answer1 |
| 01 | question2 | answer2 |
| 02 | question1 | answer3 |
| 02 | question2 | answer4 |
-----------------------------
我們想要得到的查詢結果:
------------------------------------------------------
| uid | firstname | lastname | question1 | question2 |
------------------------------------------------------
| 01 | john | doe | answer1 | answer2 |
| 02 | jane | doe | answer3 | answer4 |
------------------------------------------------------
我希望有一種直接的方法可以做到這一點,但一直找不到任何東西。 所有幫助將不勝感激。
在其他數據庫中,您可以使用PIVOT
函數,但 MySQL 沒有該函數,因此必須使用聚合函數和CASE
語句復制它。 如果您知道所有值,則可以對類似於以下內容的值進行硬編碼:
select u.uid, u.firstname, u.lastname,
max(case when question='question1' then answer else null end) as question1,
max(case when question='question2' then answer else null end) as question2
from users u
left join kv
on u.uid = kv.uid
group by u.uid, u.firstname, u.lastname;
但是如果你有未知的值,那么你可以使用准備好的語句來生成動態 SQL:
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'max(case when question = ''',
question,
''' then answer else NULL end) AS ',
question
)
) INTO @sql
FROM kv;
SET @sql = CONCAT('SELECT u.uid, u.firstname, u.lastname, ', @sql, '
from users u
left join kv
on u.uid = kv.uid
group by u.uid, u.firstname, u.lastname');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
兩個版本都會產生相同的結果:
| UID | FIRSTNAME | LASTNAME | QUESTION1 | QUESTION2 |
------------------------------------------------------
| 1 | john | doe | answer1 | answer2 |
| 2 | jane | doe | answer3 | answer4 |
准備好的語句的好處是,如果您有更改的值,那么這將在運行時生成列列表。
這將模擬 PIVOT 表:
Select
uid,
firstname,
lastname,
max(case when question = 'question1' then answer end) as question1,
max(case when question = 'question2' then answer end) as question2
From
users inner join answers on users.uid = answers.uid
Grop by uid, firstname, lastname
還有一個帶有連接的解決方案:
Select uid, firstname, lastname,
answers_1.answer as question1,
answers_2.answer as question2
From
users left join answers answers_1
on users.uid = answers_1.uid and answers_1.question = 'question1'
left join answers answers_2
on users.uid = answers_2.uid and answers_2.question = 'question2'
當然,你必須事先知道問題是什么。 如果情況並非如此,據我所知,由於 MySql 不支持 PIVOT,因此無法僅使用標准 SQL 來回答您的問題。
你可以嘗試這樣的事情:
select u.uid, u.firstname, u.lastname,
max(case when question="question1" then answer else null) as question1,
max(case when question="question2" then answer else null) as question2
from user u join answers a on u.uid = a.uid
group by u.uid, u.firstname, u.lastname
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.