Sortieren nach String oder Int

Sortieren nach String oder Int

am 11.01.2007 12:15:02 von Martin Schneider

Hallo!

Ich habe eine Tabelle mit einem Feld "Rank", das angibt, in welcher
Reihenfolde die Datensätze angezeigt werden. Diese Reihenfolge kann
Lücken enthalten. Dazu kommt noch ein Feld "Wort":
create table test(rank INT,wort VARCHAR(32));

insert into test values (1, "Arbeit");
insert into test values (2, "Arbeitsamt");
insert into test values (4, "Butter");
insert into test values (6, "Beduine");
insert into test values (8, "Bett");
insert into test values (9, "Comedy");
insert into test values (10, "Charakter");


Der Benutzer soll nun sagen können, dass er z.B. alle mit "B"
beginnenden Wörter neu alphabetisch sortiert haben will. Dabei sollten
auch die Lücken aufgeräumt werden, ohne die Reihenfolge der anderen
Buchstaben zu verändern.
Das gewünschte Ergebnis wäre also (man beachte, dass "C" nicht
alphabetisch sortiert ist, sondern die alte Reihenfolge behält):
1 Arbeit
2 Arbeitsamt
4 Beduine
5 Bett
6 Butter
7 Comedy
8 Charakter

Bevor ich mich ans Update wage, habe ich nun erstmal versucht, ein
SELECT zu basteln, das dies leistet, in etwa:

SET @rankvar=0;
SELECT @rankvar:=@rankvar+1 as newrank, test.* FROM test
ORDER BY if(SUBSTRING(wort, 0, 1)="B",wort,rank);
Problem: "rank" wird auch als String sortiert, also:
+---------+------+------------+
| newrank | rank | wort |
+---------+------+------------+
| 1 | 1 | Arbeit |
| 2 | 10 | Charakter |
| 3 | 2 | Arbeitsamt |
| 4 | 4 | Butter |
| 5 | 6 | Beduine |
| 6 | 8 | Bett |
| 7 | 9 | Comedy |
+---------+------+------------+

Wie kriege ich es hin, dass "rank" als Nummer, aber "wort" als String
sortiert wird?

Viele Grüße

Martin

Re: Sortieren nach String oder Int

am 11.01.2007 23:30:24 von dafox

Martin Schneider schrieb:

> Ich habe eine Tabelle mit einem Feld "Rank", das angibt, in welcher
> Reihenfolde die Datensätze angezeigt werden.

> Der Benutzer soll nun sagen können, dass er z.B. alle mit "B"
> beginnenden Wörter neu alphabetisch sortiert haben will. Dabei sollten
> auch die Lücken aufgeräumt werden, ohne die Reihenfolge der anderen
> Buchstaben zu verändern.

> Das gewünschte Ergebnis wäre also (man beachte, dass "C" nicht
> alphabetisch sortiert ist, sondern die alte Reihenfolge behält):

> 1 Arbeit
> 2 Arbeitsamt
> 4 Beduine
> 5 Bett
> 6 Butter
> 7 Comedy
> 8 Charakter

> SET @rankvar=0;
> SELECT @rankvar:=@rankvar+1 as newrank, test.* FROM test
> ORDER BY if(SUBSTRING(wort, 0, 1)="B",wort,rank);

RTFM! SUBSTRING() beginnt nicht mit 0, sondern mit 1. Dein ORDER BY ist
ziemlich sinnlos, weil du einfach wieder nach dem Attribut "rank"
sortierst.

Aber selbst du die Funktion richtig verwenden würdest, würde das
Resultat nicht dem entsprechen, was du erwartest.

> Problem: "rank" wird auch als String sortiert, also:

Der Ausdruck hinter dem ORDER BY wird pro Zeile ausgewertet und die
Liste wird *danach* sortiert. D.h. du bekommst in deinem Fall:

1, 2, Beduine, Bett, Butter, 7, 8

Danach wird jetzt sortiert, also werden die Zahlen alle vor die Strings
gezogen und deine Tabelle sieht danach so aus:

1 1 Arbeit
2 8 Charakter
3 2 Arbeitsamt
4 7 Comedy
5 6 Beduine
6 8 Bett
7 4 Butter

> Wie kriege ich es hin, dass "rank" als Nummer, aber "wort" als String
> sortiert wird?

Idee: Indem du "rank" vorher so verwurschtelst, dass das Sortieren als
String sinnvoll ist. Hier ein Ansatz:

SET @rankvar=0;

SELECT
@rankvar:=@rankvar+1 as newrank,
test.rank,
test.wort
FROM
test
ORDER BY
IF(wort LIKE 'B%', wort, CONCAT(SUBSTRING(wort, 1, 1), LPAD(rank, 5,
'0')))

Wenn du dir den Ausdruck, nachdem sortiert werden soll mal mit anzeigen
lässt, dann sieht das so aus:

1 Arbeit A00001
2 Arbeitsamt A00002
6 Beduine Beduine
8 Bett Bett
4 Butter Butter
9 Comedy C00009
10 Charakter C00010

Nach der dritten Spalte wird sortiert und das sollte das sein, was du
suchst.

Re: Sortieren nach String oder Int

am 13.01.2007 12:13:58 von Martin Schneider

Hi Thomas, danke für Deine Antwort.

> RTFM! SUBSTRING() beginnt nicht mit 0, sondern mit 1. Dein ORDER BY ist
> ziemlich sinnlos, weil du einfach wieder nach dem Attribut "rank"
> sortierst.
Mist, stimmt natürlich, war ein Typo. Die wirkliche Tabelle ist
komplexer, ich wollte nur für die Group ein übersichtliches Beispiel haben.

[snip]
> Idee: Indem du "rank" vorher so verwurschtelst, dass das Sortieren als
> String sinnvoll ist. Hier ein Ansatz:
>
> SET @rankvar=0;
>
> SELECT
> @rankvar:=@rankvar+1 as newrank,
> test.rank,
> test.wort
> FROM
> test
> ORDER BY
> IF(wort LIKE 'B%', wort, CONCAT(SUBSTRING(wort, 1, 1), LPAD(rank, 5,
> '0')))
Gute Idee!

Viele Grüße

Martin