0

結合テーブルに基づいて値が生成される動的な仮想列を作成したいと考えています。

タイプと呼ばれる次のテーブルがあります。

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で可能ですか?

4

2 に答える 2

3

ここでいくつかのケースの概要を説明します。

  1. 最初で最も簡単なのは次のとおりです。

    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';
    

    しかし、これにはクエリ内のすべてのタイプを手動で言及する必要があります。これは明らかにあなたが探しているものではありません。

  2. 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;
    

    小さなシェル(または他の)スクリプトを書くのは簡単なはずです。

  3. 標準SQLでは、テーブルの内容を使用してDMLステートメントを作成することはできません。データベースが異なれば、PIVOTステートメントや手続き型言語など、このためのさまざまな機能が提供されます。MySQL機能でこれを実現する方法はわかりませんが、ポイント2で概説したクエリを動的に作成して実行するという考え方です。

SQLFiddleの最初の2つのケースについて説明しました。

于 2012-07-01T08:09:34.263 に答える
1

あなたが望むことを行うという機能があり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
于 2012-07-01T07:34:22.663 に答える