ユーザー情報のレガシテーブル(まだアクティブに使用中)があり、構造を変更できません-
id name value
------------------------------
0 timezone Europe/London
0 language en
0 country 45
0 something x
1 timezone Europe/Paris
1 language fr
1 country 46
タイムゾーン/言語/国などは名前の例に過ぎず、変数にすることができます/その列の行に一意以外の有限リストはありません
返されるMySQL互換のSQLクエリが必要です-
id timezone language country something
---------------------------------------------------
0 Europe/London en 45 x
1 Europe/Paris fr 46
Pivotテーブルの機能をMySQLにハッキングすることに関するスタックオーバーフローに関するさまざまな回答を調べましたが、同じテーブルの列の一意の行値から変数列名エイリアスを使用するこのケースに一致するものはありません。私はほとんど眠っていなかったので、それらはすべて少しあいまいになり始めています、事前に謝罪します。
私が見つけることができる最も近いものは、準備されたステートメントを使用することです https://stackoverflow.com/a/986088/830171 これは最初に名前列からすべての可能な/一意の値を取得し、CASE WHEN
を使用するクエリを構築しますおよび/または同じテーブルクエリの複数のサブ_SELECT
またはJOIN
。
私が考える代替案は、そのユーザーIDのすべての行を取得してforループ内のアプリケーション自体で処理するか、名前を有限量に制限してsub SELECT
s /を使用しようとすることですJOIN
s。ただし、この2番目のオプションは、新しい名前を追加する場合には理想的ではありません。このクエリを再検討する必要があります。
明らかなものを見逃したことを教えてください
他のいくつかのRDBMSとは異なり、MySQLは設計によるこの種のピボット操作をネイティブにサポートしていません(開発者は、プレゼンテーションよりもプレゼンテーションに適していると感じていますデータベース、アプリケーションのレイヤー)。
MySQL内でこのような操作を絶対に実行する必要がある場合は、準備されたステートメントを作成する方法があります。CASE
をいじるのではなく、おそらくMySQLの GROUP_CONCAT()
関数:
SELECT CONCAT(
'SELECT `table`.id', GROUP_CONCAT('
, `t_', REPLACE(name, '`', '``'), '`.value
AS `', REPLACE(name, '`', '``'), '`'
SEPARATOR ''),
' FROM `table` ', GROUP_CONCAT('
LEFT JOIN `table` AS `t_', REPLACE(name, '`', '``'), '`
ON `table`.id = `t_', REPLACE(name, '`', '``'), '`.id
AND `t_', REPLACE(name, '`', '``'), '`.name = ', QUOTE(name)
SEPARATOR ''),
' GROUP BY `table`.id'
) INTO @qry FROM (SELECT DISTINCT name FROM `table`) t;
PREPARE stmt FROM @qry;
EXECUTE stmt;
sqlfiddle でご覧ください。
GROUP_CONCAT()
の結果は group_concat_max_len
変数によって制限されることに注意してください(デフォルトの1024バイト:いくつかの場合を除いて、ここでは関係ありません)非常に長いname
値)。