我正在使用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,并且所有类型的值都是整数。
提前致谢!
答案 0 :(得分:3)
您没有指定您正在使用的RDBMS。但这基本上是PIVOT
。
MySQL的:
如果您使用的是MySQL,它没有PIVOT
函数,但可以使用CASE
语句和聚合函数进行复制。有两种方法可以做到这一点 - 使用静态版本的值进行硬编码,或使用动态版本使用预处理语句。
静态版MySQL(见SQL fiddle with demo):
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)