結合テーブルに基づいて値が生成される動的な仮想列を作成したいと考えています。
タイプと呼ばれる次のテーブルがあります。
id, name
1, TypeA
2, TypeB
私はカテゴリと呼ばれるテーブルを持っています
id, name, type
1, a, 1
2, b, 2
次を返すクエリが欲しい
category name, TypeA, TypeB
a, 1, 0
b, 0, 1
これはmysqlで可能ですか?
結合テーブルに基づいて値が生成される動的な仮想列を作成したいと考えています。
タイプと呼ばれる次のテーブルがあります。
id, name
1, TypeA
2, TypeB
私はカテゴリと呼ばれるテーブルを持っています
id, name, type
1, a, 1
2, b, 2
次を返すクエリが欲しい
category name, TypeA, TypeB
a, 1, 0
b, 0, 1
これはmysqlで可能ですか?
ここでいくつかのケースの概要を説明します。
最初で最も簡単なのは次のとおりです。
SELECT c.name AS "CatName",
IF(typea.id IS NULL, 0, 1) AS "TypeA",
IF(typeb.id IS NULL, 0, 1) AS "TypeB"
FROM category c
LEFT JOIN types typea ON c.type = typea.id AND typea.name = 'TypeA'
LEFT JOIN types typeb ON c.type = typeb.id AND typeb.name = 'TypeB';
しかし、これにはクエリ内のすべてのタイプを手動で言及する必要があります。これは明らかにあなたが探しているものではありません。
SQLクエリを作成して使用することは可能です。このメソッドは、最初のクエリからの出力を取得して新しいクエリとして使用できるスクリプトからクエリを実行していることを前提としています。
SELECT concat('SELECT c.name AS "CatName",',
group_concat(concat('IF(',lower(t.name),
'.id IS NULL,0,1) AS "',t.name,'"')),
' FROM category c ',
group_concat(concat('LEFT JOIN types ',
lower(t.name),' ON c.type = ',lower(t.name),'.id AND ',
lower(t.name),'.name = ''',t.name,'''') SEPARATOR ' '),
';')
FROM types t;
小さなシェル(または他の)スクリプトを書くのは簡単なはずです。
標準SQLでは、テーブルの内容を使用してDMLステートメントを作成することはできません。データベースが異なれば、PIVOT
ステートメントや手続き型言語など、このためのさまざまな機能が提供されます。MySQL機能でこれを実現する方法はわかりませんが、ポイント2で概説したクエリを動的に作成して実行するという考え方です。
SQLFiddleの最初の2つのケースについて説明しました。
あなたが望むことを行うという機能がありPIVOT
ますが、残念ながらMySQLでは利用できません。
ただし、すべてのタイプをカテゴリごとに 1 つの文字列に連結することができます。
SELECT
a.name,
GROUP_CONCAT(b.name) AS types
FROM
category a
LEFT JOIN
types b ON a.type = b.id
GROUP BY
a.id
次のような結果になります。
name | types
--------------------------------
a | TypeA
b | TypeB
c | TypeA,TypeB,TypeC,TypeD
カテゴリc
には 4 つの異なるタイプがa
ありますがb
、それらに関連付けられているタイプは 1 つだけです。
チェックする s の種類と数が事前にわかってtype
いて、カテゴリにそのタイプが存在する場合にブール値を表示したい場合は、次のようにします。
SELECT,
a.name,
b.id IS NOT NULL AS TypeA,
c.id IS NOT NULL AS TypeB,
-- etc...
FROM
category a
LEFT JOIN
types b ON a.type = b.id AND b.id = 1
LEFT JOIN
types c ON a.type = c.id AND c.id = 2
-- etc...
編集:事前に作成する列の数がわからないが、タイプごとに個別の列にブール値が必要な場合は、アプリケーションロジックでクエリ文字列を動的に構築する別のオプションがあります。たとえば、PHP を使用していたとします。
$columns = $ljoins = array();
$i = 1;
foreach($pdo->query('SELECT id, name FROM types') as $row)
{
$columns[] = "t$i.id IS NOT NULL AS " . $row['name'];
$ljoins[] = "LEFT JOIN types t$i ON a.type = t$i.id AND t$i.id = " . $row['id'];
$i++;
}
$sql = 'SELECT a.name, ' . implode(', ', $columns) . ' FROM category a ' . implode(' ', $ljoins);
$stmt = $pdo->query($sql);
// Do stuff with result-set