2016-08-30 7 views
1

Ich habe diese Tabelle:Split Spalte in MySQL-Tabelle in muti Spalte Abfrage Wert in einer anderen Spalte basiert mit

Id name degree 
1 Ahmad BS 
2 John MA 
3 Abed MA 
4 Sami DR 
5 Mona BS 
6 Sara BS 

Ich möchte Namen basierend auf Grad aufzuspalten, so dass der Grad wird der Header und alle leer sein Wert in Spalte wird es mit NULL

füllen und die Namen in der Spalte werden nach Apathetically sortiert.

sollte das Ergebnis sein:

BS  MA DR 
Ahmad Abed Sami 
Mona John NULL 
Sara NULL NULL 

Was ich versucht:

SELECT 
    GROUP_CONCAT(if(degree = 'BS', name, NULL)) AS 'BS', 
    GROUP_CONCAT(if(degree = 'MA', name, NULL)) AS 'MA', 
    GROUP_CONCAT(if(degree = 'DR', name, NULL)) AS 'DR' 
    FROM persons 
    GROUP BY name; 

Aber es scheint nicht richtig.

+0

Wie viele einzigartige 'Grade' gibt es? – 1000111

+0

Nur 3 Grad (BS, MA und DR). –

+1

Obwohl es nicht unmöglich ist, dies in mysql zu tun, würde ich lieber den Pivot auf der Anwendungsseite erstellen. Es wird wahrscheinlich viel effektiver sein. – Shadow

Antwort

0
select subBS.name as BS, 
     subMA.name as MA, 
     subDR.name as DR 
from (select @rn1:=0, @rn2:=0, @rn3:=0) rn, 
    (select name, @rn1:[email protected]+1 as row 
    from t 
    where degree='BS') subBS 
    full outer join 
    (select name, @rn1:[email protected]+1 as row 
    from t 
    where degree='MA') subMA on subBS.row=subMA.row 
    full outer join 
    (select name, @rn1:[email protected]+1 as row 
    from t 
    where degree='DR') subDR on subBS.row=subDR.row 

Ein weiterer Versuch, basierend auf künstliche Unterabfrage wo amout der Zeilen größer als in jeder Unterabfrage

Wir definieren Unterabfrage Anzahl Zeilen basierend auf dem Tisch, ohne Einschränkungen und dann leere Datensätze überspringen

select subBS.name as BS, 
     subMA.name as MA, 
     subDR.name as DR 
from (select @rn:=0, @rn1:=0, @rn2:=0, @rn3:=0) rn, 
    (select @rn:[email protected]+1 as row 
    from t) as main 
    left outer join on main.row=subMA.row 
    (select name, @rn1:[email protected]+1 as row 
    from t 
    where degree='BS' 
    order by name) subBS 
    left outer join 
    (select name, @rn2:[email protected]+1 as row 
    from t 
    where degree='MA' 
    order by name) subMA on main.row=subMA.row 
    left outer join 
    (select name, @rn3:[email protected]+1 as row 
    from t 
    where degree='DR' 
    order by name) subDR on main.row=subDR.row 
where subBS.name is not null 
    or subMA.name is not null 
    or subDR.name is not null 
+0

Mysql unterstützt keine vollständige äußere verbindet. – Shadow

+0

@Shadow Sie haben Recht. Es ist möglich, sie zu emulieren http://stackoverflow.com/questions/4796872/full-outer-join-in-mysql. Oder wir müssen irgendwie Max Zeilen für jede der Unterabfragen bekommen und die erste Sub mit Max Zeilen setzen und LEFT JOIN die anderen 2 Subs verwenden – StanislavL

+0

Ich glaube, wenn Sie eine benutzerdefinierte Variable in der äußeren Abfrage inkrementieren, dann wird das den Job erledigen, aber du solltest es testen. – Shadow

1
SET @rn1 := 0, @rn2 := 0, @rn3 := 0; 

SELECT MAX(bs) AS `BS`, 
     MAX(ms) AS `MS`, 
     MAX(dr) AS `DR` 
FROM (
    SELECT CASE WHEN degree = 'BS' THEN @rn1 := @rn1 + 1 
      WHEN degree = 'MA' THEN @rn2 := @rn2 + 1 
      WHEN degree = 'DR' THEN @rn3 := @rn3 + 1 
     END AS `Row Number`, 
     IF(degree = 'BS', name, NULL) AS `bs`, 
     IF(degree = 'MA', name, NULL) AS `ma`, 
     IF(degree = 'DR', name, NULL) AS `dr` 
    FROM persons 
    ORDER BY name 
) AS temp 
GROUP BY `Row Number` 

Da wir Werte aus verschiedenen Zeilen in der Originaltabelle in derselben Zeile in der geschwenkten Tabelle speichern möchten, können wir für jede Zeile einen eigenen Zeilennummernzähler einrichten Spalte (in diesem Fall drei Zähler für drei Arten von Graden), so können wir sie alle in der gleichen Zeile entsprechend ihrer Zeilennummer platzieren.

In der temporären Tabelle führen wir alle Werte in separaten Zeilen auf und füllen andere Zellen in einer Zeile mit NULL. Wir erhöhen auch die Zähler in Abhängigkeit vom Grad-Typ. Zurück in der äußeren Abfrage können wir die MAX() (oder MIN()) Funktion verwenden, um den einzigen Nicht-NULL-Wert in dieser Spalte für diese bestimmte Zeilennummer anzuzeigen.

Ich hoffe, das hilft jemandem. Ich war auf der Suche nach einer Antwort auf ein fast identisches Problem, und ich beschloss, mich bei StackExchange anzumelden, als ich es endlich gefunden habe, damit ich diese Frage beantworten kann. SE's Community hat mir so oft hilfreiche Lösungen geliefert, dass es nur fair erschien :)

Verwandte Themen