0

MS SQL Server 2012 Express を使用しています

私のクエリは次のとおりです。

select invTypeMaterials.[typeID], invTypes.[typeName], invTypeMaterials.[quantity] from invTypeMaterials
  inner join invTypes
    on invTypeMaterials.materialTypeID = invTypes.[typeID]

私の結果は次のようになります。

typeID | typeName | quantity
18     | Blah1    | Integer
18     | Blah2    | Integer
...    | ...      | ...
36     | Blah1    | Integer
36     | Blah1    | Integer

結果が次のようになることを本当に望んでいます。

typeID | Blah1   | Blah2   | ... | Blah7
18     | Integer | Integer | ... | Integer
...
36     | Integer | Integer | ... | Integer

これは、データを外部で解析した場合に可能ですが、これをすべてうまく簡単に実行できる気の利いた SQL ステートメントがあることを願っています。型には Blah1 から Blah7 までしかなく、型のすべての値は整数です。

前もって感謝します!

4

1 に答える 1

3

使用している RDBMS を指定していません。しかし、これは基本的にPIVOT.

MySQL:

MySQL を使用している場合、関数はありませんが、ステートメントと集計関数PIVOTを使用して複製できます。CASEこれを行うには 2 つの方法があります。値がハードコードされている静的バージョンか、準備済みステートメントを使用する動的バージョンのいずれかです。

静的バージョンの MySQL (デモの SQL フィドルを参照):

select m.typeID,
  sum(case when t.typename = 'type 1' then m.quantity else 0 end) Type1,
  sum(case when t.typename = 'type 2' then m.quantity else 0 end) Type2,
  sum(case when t.typename = 'type 3' then m.quantity else 0 end) Type3
from invTypeMaterials m
inner join invTypes t
  on m.typeID = t.typeID
group by m.TypeId;

動的バージョン MySQL ( SQL Fiddle with Demoを参照):

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'sum(case when t.typename = ''',
      t.typename,
      ''' then m.quantity else 0 end) ',
      replace(t.typename, ' ', '')
    )
  ) INTO @sql
from invTypeMaterials m
inner join invTypes t
  on m.typeID = t.typeID;

SET @sql = CONCAT('SELECT m.typeID, ', @sql, ' 
                  from invTypeMaterials m
                  inner join invTypes t
                    on m.typeID = t.typeID
                   GROUP BY m.TypeId');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SQL Server にはPIVOT関数があり、これを静的または動的に行うことができます。

静的バージョンの SQL Server ( SQL Fiddle with Demoを参照):

select typeid,
  isnull([Type 1], 0) type1,
  isnull([Type 2], 0) type2,
  isnull([Type 3], 0) type3
from 
(
  select m.TypeId,
    m.quantity,
    t.typename
  from invTypeMaterials m
  inner join invTypes t
    on m.typeID = t.typeID
) x
pivot
(
  sum(quantity)
  for typename in ([Type 1], [Type 2], [Type 3])
) p

動的バージョンの SQL Server ( SQL Fiddle with Demoを参照):

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX),
    @colsNull as nvarchar(max)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(typename) 
                    from invTypes
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

select @colsNull 
    = STUFF((SELECT distinct ', IsNull(' + QUOTENAME(typename) + ', 0) as '+ replace(typename, ' ', '') 
                    from invTypes
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT typeid, ' + @colsNull + ' from 
             (
                select m.TypeId,
                  m.quantity,
                  t.typename
                from invTypeMaterials m
                inner join invTypes t
                  on m.typeID = t.typeID
            ) x
            pivot 
            (
                sum(quantity)
                for typename in (' + @cols + ')
            ) p '

execute(@query)
于 2012-10-17T01:08:09.373 に答える