Pivot / Crosstab - Spalten nummerieren?

Pivot / Crosstab - Spalten nummerieren?

am 16.10.2006 20:23:00 von Markus Ernst

Hallo

Ich quäle mich nun seit 3 Tagen damit ab, kriege es aber nicht raus...
Ich mache eine temporäre Tabelle um Bücher mit variabler Zahl von
Autorinnen und Autoren zu sortieren. Soweit bin ich:

Tabelle sort_strings:
| buch | str |
+------+-----------+
| 1 | Gross |
| 1 | Hänschen |
| 1 | Meier |
| 1 | Markus |
| 1 | Schmidt |
| 1 | Anna |
| 2 | Schneider |
| 2 | Gerda |
| 3 | Hermann |
| 3 | Frank |
| 3 | Klein |
| 3 | Lisa |

Der Versuch dies Abzufragen:
SELECT b.id FROM buecher AS b
LEFT JOIN sort_strings AS s ON b.id = s.buch
GROUP BY b.id
ORDER BY s.str, b.titel

scheitert (wohl unter anderem) daran, dass ich nicht vor dem Gruppieren
sortieren kann.

Ganz einfach wäre es, wenn ich die sort_strings umwandeln könnte in:

| buch | str0 | str1 | str2 | str3 | str4 | str5 |
+------+-----------+----------+-------+--------+---------+-- ----+
| 1 | Gross | Hänschen | Meier | Markus | Schmidt | Anna |
| 2 | Schneider | Gerda | NULL | NULL | NULL | NULL |
| 3 | Hermann | Frank | Klein | Lisa | NULL | NULL |

Dieses Problem wurde ja schon behandelt - die Antworten weisen immer auf
die Suchbegriffe "Pivot table" und "Crosstab" hin. Aus den Beispielen,
die sich dazu finden, finde ich aber nicht heraus, wie ich die
Spaltennamen hinkriege. Mit Count(), Sum(), Max() etc. kann man zwar das
ganze Resultat-Set auswerten, aber wie ich auf einen Spalten-Index
komme, krieg ich nicht raus...

Ich wäre extrem dankbar für einen Hinweis, in welche Richtung ich weiter
suchen könnte!

--
Markus

Re: Pivot / Crosstab - Spalten nummerieren?

am 16.10.2006 22:07:55 von Sebastian Suchanek

Markus Ernst schrieb:
> [...]
> Dieses Problem wurde ja schon behandelt - die Antworten weisen immer auf
> die Suchbegriffe "Pivot table" und "Crosstab" hin. Aus den Beispielen,
> die sich dazu finden, finde ich aber nicht heraus, wie ich die
> Spaltennamen hinkriege. Mit Count(), Sum(), Max() etc. kann man zwar das
> ganze Resultat-Set auswerten, aber wie ich auf einen Spalten-Index
> komme, krieg ich nicht raus...

Hilft Dir evtl. ff., speziell
weiter?


Tschüs,

Sebastian

Re: Pivot / Crosstab - Spalten nummerieren?

am 17.10.2006 10:15:51 von Markus Ernst

Sebastian Suchanek schrieb:
> Markus Ernst schrieb:
>> [...]
>> Dieses Problem wurde ja schon behandelt - die Antworten weisen immer auf
>> die Suchbegriffe "Pivot table" und "Crosstab" hin. Aus den Beispielen,
>> die sich dazu finden, finde ich aber nicht heraus, wie ich die
>> Spaltennamen hinkriege. Mit Count(), Sum(), Max() etc. kann man zwar das
>> ganze Resultat-Set auswerten, aber wie ich auf einen Spalten-Index
>> komme, krieg ich nicht raus...
>
> Hilft Dir evtl. ff., speziell
> weiter?

Danke, dies hatte ich schon gelesen und ausprobiert. GROUP_CONCAT()
gibts leider erst ab MySQL 4.1; da meine Applikation für Shared Hosting
ausgelegt ist, kann ich mich vorläufig leider nicht darauf verlassen.

Übrigens ist mir eine Tabellen-Lösung auch lieber, weil in gewissen
Fällen zusammengesetzte Strings anders sortiert werden, als wenn die
Namen in separaten Feldern liegen:

Tabelle1:
| id | str0 | str1 | str2 | str3 |
+----+-------+--------------+--------+------+
| 1 | Meier | Hanna | Albers | Hans |
| 2 | Meier | Hanna Sophie | Albers | Hans |
| 3 | Meier | Hanna | Ulrich | Hans |

SELECT id FROM Tabelle1 ORDER BY str0, str1, str2, str3
-> 1, 3, 2

Tabelle2:
| id | str |
+----+---------------------------------+
| 1 | Meier Hanna, Albers Hans |
| 2 | Meier Hanna Sophie, Albers Hans |
| 3 | Meier Hanna, Ulrich Hans |

SELECT id FROM Tabelle2 ORDER BY str
-> 2, 1, 3

Tabelle3:
| id | str |
+----+--------------------------------+
| 1 | Meier Hanna Albers Hans |
| 2 | Meier Hanna Sophie Albers Hans |
| 3 | Meier Hanna Ulrich Hans |

SELECT id FROM Tabelle3 ORDER BY str
-> 1, 2, 3

Ich bin also wohl darauf angewiesen, meine Sortierstrings irgendwie in
die Form der Tabelle1 zu kriegen...

--
Markus

Re: Pivot / Crosstab - Spalten nummerieren?

am 17.10.2006 10:39:54 von Kris

Markus Ernst wrote:
> Danke, dies hatte ich schon gelesen und ausprobiert. GROUP_CONCAT()
> gibts leider erst ab MySQL 4.1; da meine Applikation für Shared Hosting
> ausgelegt ist, kann ich mich vorläufig leider nicht darauf verlassen.

Ältere Versionen als 4.1 sind deprecated und aus dem Support. Wo die noch
laufen, laufen die ganz alleine...

Kris

Re: Pivot / Crosstab - Spalten nummerieren?

am 17.10.2006 10:59:52 von Markus Ernst

Kristian Köhntopp schrieb:
> Markus Ernst wrote:
>> Danke, dies hatte ich schon gelesen und ausprobiert. GROUP_CONCAT()
>> gibts leider erst ab MySQL 4.1; da meine Applikation für Shared Hosting
>> ausgelegt ist, kann ich mich vorläufig leider nicht darauf verlassen.
>
> Ältere Versionen als 4.1 sind deprecated und aus dem Support. Wo die noch
> laufen, laufen die ganz alleine...

Danke, ich werde meinen Provider darauf hinweisen... Ich hoffe, dass
damit meine ursprüngliche Frage nicht vergessen ist; ich hatte ja eben
beschrieben, wieso eine Lösung mit GROUP_CONCAT() nicht optimal ist :-)

--
Markus

Re: Pivot / Crosstab - Spalten nummerieren?

am 17.10.2006 11:15:47 von Sebastian Suchanek

Kristian Köhntopp schrieb:
> Markus Ernst wrote:
>> Danke, dies hatte ich schon gelesen und ausprobiert. GROUP_CONCAT()
>> gibts leider erst ab MySQL 4.1; da meine Applikation für Shared Hosting
>> ausgelegt ist, kann ich mich vorläufig leider nicht darauf verlassen.
>
> Ältere Versionen als 4.1 sind deprecated und aus dem Support. Wo die noch
> laufen, laufen die ganz alleine...

Mag sein - aber z.B. Debian Sarge ist deren aktuelles stable
release und das installiert standardmäßig v4.0 - wenn man v4.1
möchte, muß man das explizit wählen.

(Und dank der Unfähigkeit meines derzeitigen vServer-Hosters darf
ich demnächst Confixx aus einem laufenden System herausfummeln,
weil dessen selbstgebackenes Confixx-Paket nicht mit dem
MySQL-4.1-Paket zusammen sein will. :-( )


Tschüs,

Sebastian

Re: Pivot / Crosstab - Spalten nummerieren?

am 17.10.2006 17:00:09 von Kris

Sebastian Suchanek wrote:
> Mag sein - aber z.B. Debian Sarge ist deren aktuelles stable
> release und das installiert standardmäßig v4.0 - wenn man v4.1
> möchte, muß man das explizit wählen.

Ähm, Debian installiert 4.1 und man kann 5.0 wählen.

Kris

[Solved?] Re: Pivot / Crosstab - Spalten nummerieren?

am 17.10.2006 17:00:31 von Markus Ernst

Markus Ernst schrieb:
> Ich bin also wohl darauf angewiesen, meine Sortierstrings irgendwie in
> die Form der Tabelle1 zu kriegen...
>
Uff - mit Self-Join und einer zusätzlichen Auto-Increment-Spalte habe
ich eine funktionierende Fassung hingekriegt:

CREATE TEMPORARY TABLE IF NOT EXISTS temp0 (
a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
buch INT UNSIGNED NOT NULL,
str TINYTEXT
) ENGINE=MyISAM;

Gefüllt ist das also meine Ausgangstabelle temp0:

| a | buch | str |
+----+------+-----------+
| 1 | 1 | Gross |
| 2 | 1 | Hänschen |
| 3 | 1 | Meier |
| 4 | 1 | Markus |
| 5 | 1 | Schmidt |
| 6 | 1 | Anna |
| 7 | 2 | Schneider |
| 8 | 2 | Gerda |
| 9 | 3 | Hermann |
| 10 | 3 | Frank |
| 11 | 3 | Klein |
| 12 | 3 | Lisa |

Nachdem ich eruiert habe, wieviele gleiche buch-Einträge es maximal gibt
(in diesem Fall 6), muss ich Kopien der Tabelle anlegen, da temporäre
Tabellen pro Query nur einmal verwendet werden können:

CREATE TEMPORARY TABLE IF NOT EXISTS temp1 (
a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
buch INT UNSIGNED NOT NULL,
str TINYTEXT
) ENGINE=MERGE UNION=(temp0);
.... und dasselbe für temp2 bis temp5.

(Das habe ich von
http://dev.mysql.com/doc/refman/4.1/en/create-table.html, User-Kommentar
vom 25. Mai 2006)

So gehts dann ohne IF, CASE und Ähnliches:

CREATE TEMPORARY TABLE IF NOT EXISTS sort_strings
SELECT temp0.buch,
temp0.str AS str0,
temp1.str AS str1,
temp2.str AS str2,
temp3.str AS str3,
temp4.str AS str4,
temp5.str AS str5
FROM temp0
LEFT JOIN temp1 ON temp1.buch = temp0.buch AND temp1.a = temp0.a + 1
LEFT JOIN temp2 ON temp2.buch = temp1.buch AND temp2.a = temp1.a + 1
LEFT JOIN temp3 ON temp3.buch = temp2.buch AND temp3.a = temp2.a + 1
LEFT JOIN temp4 ON temp4.buch = temp3.buch AND temp4.a = temp3.a + 1
LEFT JOIN temp5 ON temp5.buch = temp4.buch AND temp5.a = temp4.a + 1
GROUP BY temp0.buch;

Das ergibt die Tabelle sort_strings:

| buch | str0 | str1 | str2 | str3 | str4 | str5 |
+------+-----------+----------+-------+--------+---------+-- ----+
| 1 | Gross | Hänschen | Meier | Markus | Schmidt | Anna |
| 2 | Schneider | Gerda | NULL | NULL | NULL | NULL |
| 3 | Hermann | Frank | Klein | Lisa | NULL | NULL |

Ob es nicht eine weniger umständliche Methode gäbe? Sagen wir, wir könnten:
- Abfragen, zum wievielten Mal der Wert in einer Spalte vorkommt, z.B.
mit einer Funktion die hiesse "get_duplicate_value_index()"
- Aliase wie Strings zusammensetzen
Dann wäre mit der Tabelle temp0 sowas denkbar:

SELECT buch, str AS CONCAT('str', GET_DUPLICATE_VALUE_INDEX(str)) FROM
temp0 GROUP BY buch;

--
Markus

Re: Pivot / Crosstab - Spalten nummerieren?

am 17.10.2006 17:02:54 von Sven Paulus

Kristian Köhntopp wrote:
>> Mag sein - aber z.B. Debian Sarge ist deren aktuelles stable
>> release und das installiert standardmäßig v4.0 - wenn man v4.=
1
>> möchte, muß man das explizit wählen.

> Ähm, Debian installiert 4.1 und man kann 5.0 wählen.


Nicht bei Sarge (Debian 3.1), dort gibt es die Pakete mysql-server
(4.0) und mysql-server-4.1 (4.1). Alles andere muss man von
dotdeb.org oder backports.org ziehen oder selbst bauen.

Re: [Solved?] Re: Pivot / Crosstab - Spalten nummerieren?

am 17.10.2006 17:04:22 von Markus Ernst

Markus Ernst schrieb:
> Ob es nicht eine weniger umständliche Methode gäbe? Sagen wir, wir könnten:
> - Abfragen, zum wievielten Mal der Wert in einer Spalte vorkommt, z.B.
> mit einer Funktion die hiesse "get_duplicate_value_index()"
> - Aliase wie Strings zusammensetzen
> Dann wäre mit der Tabelle temp0 sowas denkbar:
>
> SELECT buch, str AS CONCAT('str', GET_DUPLICATE_VALUE_INDEX(str)) FROM
> temp0 GROUP BY buch;
>

str AS CONCAT('str', GET_DUPLICATE_VALUE_INDEX(buch))
^^^^
natürlich...

Re: Pivot / Crosstab - Spalten nummerieren?

am 18.10.2006 16:25:58 von Norbert Tretkowski

* Kristian Köhntopp wrote:
> Sebastian Suchanek wrote:
>> Mag sein - aber z.B. Debian Sarge ist deren aktuelles stable release
>> und das installiert standardmäßig v4.0 - wenn man v4.1 möchte, muß
>> man das explizit wählen.
>
> Ähm, Debian installiert 4.1 und man kann 5.0 wählen.

Das stimmt weder fuer sarge, noch fuer etch.

Norbert

Re: Pivot / Crosstab - Spalten nummerieren?

am 20.10.2006 18:25:02 von Kris

Norbert Tretkowski wrote:
>> Ähm, Debian installiert 4.1 und man kann 5.0 wählen.
>
> Das stimmt weder fuer sarge, noch fuer etch.

Dann hat Debian ein schweres Problem.

http://www.mysql.com/company/legal/lifecycle/

Kris

Re: Pivot / Crosstab - Spalten nummerieren?

am 21.10.2006 20:56:07 von Norbert Tretkowski

* Kristian Köhntopp wrote:
> Norbert Tretkowski wrote:
>>> Ähm, Debian installiert 4.1 und man kann 5.0 wählen.
>>
>> Das stimmt weder fuer sarge, noch fuer etch.
>
> Dann hat Debian ein schweres Problem.

Noch nicht.

Norbert

Re: Pivot / Crosstab - Spalten nummerieren?

am 22.10.2006 10:36:56 von Sven Paulus

Kristian Köhntopp wrote:
>>> Ähm, Debian installiert 4.1 und man kann 5.0 wählen.
>> Das stimmt weder fuer sarge, noch fuer etch.
> Dann hat Debian ein schweres Problem.
> http://www.mysql.com/company/legal/lifecycle/

Spielt das in diesem Fall wirklich eine Rolle? Wuerde MySQL
ueberhaupt Support fuer die von Debian ausgelieferten Binaries bieten?

Security-Patches macht Debian ja eh selbst, bei 3.23 ist ja
auch damals bei Woody alles bei 3.23.49 stehen geblieben und die
ganzen relevanten Fixes eben dort reingearbeitet worden.