2015-12-18 11 views
5

Ich versuche, einige Daten in einer Tabelle PIVOT, aber ich kann es nicht tun, weil ich nicht den Weg finden, es mit Varchar-Spalten zu tun. Ich habe diese Tabelle:Pivot-Spalte von varchar

declare @table table(name VARCHAR(50) not null, occupation VARCHAR(MAX)) 

insert into @table values ('A','Doctor') 
insert into @table values ('B','Doctor') 
insert into @table values ('A','Professor') 
insert into @table values ('A','Singer') 
insert into @table values ('A','Actor') 

SELECT 

CASE WHEN occupation = 'Doctor' THEN NAME END AS Doctor, 
CASE WHEN occupation = 'Professor' THEN NAME END AS Professor, 
CASE WHEN occupation = 'Singer' THEN NAME END AS Singer, 
CASE WHEN occupation = 'Actor' THEN NAME END AS Actor 
FROM @table 

Ausgang:

Doctor Professor Singer Actor 
A NULL NULL NULL 
B NULL NULL NULL 
NULL A NULL NULL 
NULL NULL A NULL 
NULL NULL NULL A 

Und für Pivot bekomme ich diese Ausgabe:

select * from 
(
select name, occupation from @table) src 
pivot (
min(name) 
for occupation in ([Doctor],[Professor],[Singer],[Actor])) as pvt 

Doctor Professor Singer Actor 
A  A   A  A 

Und für min/max/Funktion, um die Pivot-Funktion gibt mir nur teilweise Ausgabe, für die Zählfunktion bekomme ich die Anzahl der Datensätze für Arzt, Sänger etc .. Aber ich brauche aktuelle Zeilen, nicht die Zeilenanzahl.

Was ich brauche, ist dies:

Doctor Professor Singer Actor 
A  A   A  A 
B  NULL  NULL NULL 

d.h nehme an, wenn wir 5 Namen für Ärzte brauchen wir 5 Einträge für den Arzt Spalte zeigen.

Antwort

2

Das finde ich einfacher als bedingte Aggregation zum Ausdruck bringen eine laufende Nummer erzeugt unter Verwendung von mit `row_number():

select max(case when occupation = 'Doctor' then name end) as Doctor, 
     max(case when occupation = 'Professor' then name end) as Professor, 
     max(case when occupation = 'Singer' then name end) as Singer, 
     max(case when occupation = 'Actor' then name end) as Actor  
from (select t.*, 
      row_number() over (partition by occupation order by name) as seqnum 
     from @table t 
    ) t 
group by seqnum 
order by seqnum; 
+0

Dank! :). Aber Order by ist nicht in aufsteigender Reihenfolge für andere Datensätze bestellen, Eigentlich muss ich alle Spalten in aufsteigender Reihenfolge, So gab ich Bestellung von 1,2,3,4 – MAX

+0

@ max. . . Wenn Sie die Namen in aufsteigender Reihenfolge wünschen, verwenden Sie 'order by name' in der' order by'-Klausel für 'row_number()'. –

+0

Ich fühlte, dass wir das mit row_number() tun können, und tatsächlich habe ich die Unterabfrage auch separat geschrieben. Aber ich wusste nicht, dass ich sowohl die case-Anweisung der äußeren als auch der tatsächlichen Spalte mit rowid der inneren Abfrage zusammenführen sollte. – MAX

1

Sie PIVOT verwenden können, wie Sie vorgeschlagen, fügen Sie einfach Spalte mit ROW_NUMBER:

SELECT [Doctor],[Professor],[Singer],[Actor] 
FROM (SELECT name, occupation, 
      rn = ROW_NUMBER() OVER (PARTITION BY occupation ORDER BY occupation) 
     FROM @table) AS src 
PIVOT (
    MIN(name) 
    FOR occupation IN ([Doctor],[Professor],[Singer],[Actor]) 
) AS pvt 

LiveDemo

Ausgang:

╔════════╦═══════════╦════════╦═══════╗ 
║ Doctor ║ Professor ║ Singer ║ Actor ║ 
╠════════╬═══════════╬════════╬═══════╣ 
║ A  ║ A   ║ A  ║ A  ║ 
║ B  ║   ║  ║  ║ 
╚════════╩═══════════╩════════╩═══════╝ 

EDIT:

Sie schreiben nicht, wie mehr Zeilen zu handhaben, so diesen Fall in Betracht ziehen. Above Lösung zurück:

╔════════╦═══════════╦════════╦═══════╗ 
║ Doctor ║ Professor ║ Singer ║ Actor ║ 
╠════════╬═══════════╬════════╬═══════╣ 
║ A  ║ A   ║ A  ║ A  ║ 
║ B  ║   ║ C  ║  ║ 
╚════════╩═══════════╩════════╩═══════╝ 

vs:

╔════════╦═══════════╦════════╦═══════╗ 
║ Doctor ║ Professor ║ Singer ║ Actor ║ 
╠════════╬═══════════╬════════╬═══════╣ 
║ A  ║ A   ║ A  ║ A  ║ 
║ B  ║   ║  ║  ║ 
║  ║   ║ C  ║  ║ 
╚════════╩═══════════╩════════╩═══════╝ 

Wenn Sie zweiten Fall verwenden möchten:

SELECT [Doctor],[Professor],[Singer],[Actor] 
FROM (SELECT name, occupation, 
      rn = DENSE_RANK() OVER (ORDER BY Name) 
     FROM @table) AS src 
PIVOT (
    MIN(name) 
    FOR occupation IN ([Doctor],[Professor],[Singer],[Actor]) 
) AS pvt 

LiveDemo2

+1

Hi @ lad2025, Netter Beitrag. Eigentlich brauche ich alle Spalten in aufsteigender Reihenfolge bestellt werden – MAX

+0

@max Bitte siehe aktualisiert – lad2025

+0

danke @ lad2025 Sorry ich versuche, von auf der Außenseite Abfrage bestellen – MAX