Diese Art der Transformation ein Dreh genannt wird. Sie haben nicht angegeben, welche Datenbank Sie verwenden, daher werde ich eine Antwort für SQL Server und MySQL geben.
SQL Server: Wenn Sie SQL Server verwenden 2005+ Sie die PIVOT
Funktion implementieren können.
Wenn Sie eine bekannte Anzahl von Werten haben, die Sie in Spalten konvertieren möchten, können Sie die Abfrage fest codieren.
select typename, total, Deployed, Inventory, shipped
from
(
select count(*) over(partition by t.typename) total,
s.statusname,
t.typename
from assets a
inner join assettypes t
on a.assettype = t.id
inner join assetstatus s
on a.assetstatus = s.id
) d
pivot
(
count(statusname)
for statusname in (Deployed, Inventory, shipped)
) piv;
Siehe SQL Fiddle with Demo.
Aber wenn Sie eine unbekannte Anzahl von status
Werte haben, dann müssen Sie dynamische SQL verwenden, um die Liste der Spalten zur Laufzeit zu generieren.
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(statusname)
from assetstatus
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT typename, total,' + @cols + ' from
(
select count(*) over(partition by t.typename) total,
s.statusname,
t.typename
from assets a
inner join assettypes t
on a.assettype = t.id
inner join assetstatus s
on a.assetstatus = s.id
) x
pivot
(
count(statusname)
for statusname in (' + @cols + ')
) p '
execute(@query)
Siehe SQL Fiddle with Demo
Dies kann auch mit einem Fall unter Verwendung des Ausdrucks eine Aggregatfunktion geschrieben werden:
select typename,
total,
sum(case when statusname ='Deployed' then 1 else 0 end) Deployed,
sum(case when statusname ='Inventory' then 1 else 0 end) Inventory,
sum(case when statusname ='Shipped' then 1 else 0 end) Shipped
from
(
select count(*) over(partition by t.typename) total,
s.statusname,
t.typename
from assets a
inner join assettypes t
on a.assettype = t.id
inner join assetstatus s
on a.assetstatus = s.id
) d
group by typename, total
Siehe SQL Fiddle with Demo
MySQL: Diese Datenbank tun Es hat keine Pivot Funktion, so dass Sie die Aggregatfunktion und eine CASE
Ausdruck verwenden müssen. Es hat auch nicht funktioniert Windowing, so dass Sie die Abfrage leicht an folgende ändern müssen:
select typename,
total,
sum(case when statusname ='Deployed' then 1 else 0 end) Deployed,
sum(case when statusname ='Inventory' then 1 else 0 end) Inventory,
sum(case when statusname ='Shipped' then 1 else 0 end) Shipped
from
(
select t.typename,
(select count(*)
from assets a1
where a1.assettype = t.id
group by a1.assettype) total,
s.statusname
from assets a
inner join assettypes t
on a.assettype = t.id
inner join assetstatus s
on a.assetstatus = s.id
) d
group by typename, total;
Siehe SQL Fiddle with Demo
Dann, wenn Sie eine dynamische Lösung in MySQL benötigen, müssen Sie ein verwenden vorbereitete Anweisung generieren die sQL-Zeichenfolge ausführen:
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'sum(CASE WHEN statusname = ''',
statusname,
''' THEN 1 else 0 END) AS `',
statusname, '`'
)
) INTO @sql
FROM assetstatus;
SET @sql
= CONCAT('SELECT typename,
total, ', @sql, '
from
(
select t.typename,
(select count(*)
from assets a1
where a1.assettype = t.id
group by a1.assettype) total,
s.statusname
from assets a
inner join assettypes t
on a.assettype = t.id
inner join assetstatus s
on a.assetstatus = s.id
) d
group by typename, total');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Siehe SQL Fiddle with Demo.
Das Ergebnis ist das gleiche für alle Anfragen in beiden Datenbanken:
| TYPENAME | TOTAL | DEPLOYED | INVENTORY | SHIPPED |
-----------------------------------------------------
| Desktop | 2 | 1 | 1 | 0 |
| Laptop | 1 | 0 | 0 | 1 |
| Server | 1 | 1 | 0 | 0 |
Welche RDBMS verwenden Sie? – Taryn
Woher kommen die (75, 56, 50) implementierten Werte? Sie erscheinen nicht in Ihren Daten. –
Das macht für mich im Moment keinen großen Sinn Haben Sie einige Beispiele dafür, was in Ihren Tabellen steht, ein paar tatsächliche Zeilen ... Es muss einige Gemeinsamkeiten zwischen den Tabellen als Bezugspunkt geben verbinden Sie sie miteinander ... Wenn Sie dieses Detail liefern, werde ich es ausprobieren. –