VARCHAR-Spalte nach bestimmter Reihenfolge sortieren

VARCHAR-Spalte nach bestimmter Reihenfolge sortieren

am 05.06.2007 02:20:48 von Holger Pollmann

Hallo,

folgendes: ich habe eine MyISAM-Tabelle in einer MYSQL-5.0-Datenbank
mit einer Spalte "typ", die in einer bestimmten Weise sortiert werden
soll, nämlich in einer bestimmten Reihenfolge, die nicht alphabetisch
ist. (Normalerweise würde ich ein ENUM deklarieren, aber hier müssen
die Werte frei definierbar sein.)

Am besten wäre es, wenn so etwas ginge wie
Zuerst 'hallo',
dann 'autobahn',
dann 'welt',
dann 'bahn',
dann alles andere alphabetisch

Wenn das nicht geht, würde mir auch
Zuerst 'hallo',
dann 'autobahn',
dann 'welt',
dann 'bahn',
dann alles andere

helfen.

Und ich stehe irgendwie auf dem Schlaucht. Am bestem wäre vermutlich
eine Art Funktion, die je nach Typ eine Zahl zurückgibt oder so?

Für Hilfe oder einen Schubs in die richtige Richtung wäre ich dankbar.

--
( ROT-13 if you want to email me directly: uvuc@ervzjrexre.qr )
"Das saarl. VwVfG läßt eine Interpretation deutscher Gesetze nur dann
zu, wenn sie nicht eindeutig sind." Manfred Saar, Präsident
Apothekerkammer d. Saarlandes. heute-journal v. 8. August 2006.

Re: VARCHAR-Spalte nach bestimmter Reihenfolge sortieren

am 05.06.2007 02:32:37 von B.Steinbrink

On Tue, 05 Jun 2007 00:20:48 +0000, Holger Pollmann wrote:

> Hallo,
>
> folgendes: ich habe eine MyISAM-Tabelle in einer MYSQL-5.0-Datenbank mit
> einer Spalte "typ", die in einer bestimmten Weise sortiert werden soll,
> nämlich in einer bestimmten Reihenfolge, die nicht alphabetisch ist.
> (Normalerweise würde ich ein ENUM deklarieren, aber hier müssen die
> Werte frei definierbar sein.)
>
> Am besten wäre es, wenn so etwas ginge wie
> Zuerst 'hallo',
> dann 'autobahn',
> dann 'welt',
> dann 'bahn',
> dann alles andere alphabetisch
>
> Wenn das nicht geht, würde mir auch
> Zuerst 'hallo',
> dann 'autobahn',
> dann 'welt',
> dann 'bahn',
> dann alles andere
>
> helfen.
>
> Und ich stehe irgendwie auf dem Schlaucht. Am bestem wäre vermutlich
> eine Art Funktion, die je nach Typ eine Zahl zurückgibt oder so?

Spontan fällt mir da nur FIND_IN_SET ein, und das muss man auch noch
rückwärts konstruieren.

.... ORDER BY FIND_IN_SET(feld, 'bahn,welt,autobahn,hallo') DESC, feld ASC;

Dürfte nicht sonderlich effizient sein, und laut Handbuch geht's kaputt,
falls der Wert in "feld" ein Komma enthält :-( Noch jemand mit besseren
Vorschlägen zur Stelle?

Björn

Re: VARCHAR-Spalte nach bestimmter Reihenfolge sortieren

am 05.06.2007 11:27:58 von Robert Klemme

On 05.06.2007 02:20, Holger Pollmann wrote:
> Hallo,
>
> folgendes: ich habe eine MyISAM-Tabelle in einer MYSQL-5.0-Datenbank
> mit einer Spalte "typ", die in einer bestimmten Weise sortiert werden
> soll, nämlich in einer bestimmten Reihenfolge, die nicht alphabetisch
> ist. (Normalerweise würde ich ein ENUM deklarieren, aber hier müssen
> die Werte frei definierbar sein.)
>
> Am besten wäre es, wenn so etwas ginge wie
> Zuerst 'hallo',
> dann 'autobahn',
> dann 'welt',
> dann 'bahn',
> dann alles andere alphabetisch
>
> Wenn das nicht geht, würde mir auch
> Zuerst 'hallo',
> dann 'autobahn',
> dann 'welt',
> dann 'bahn',
> dann alles andere
>
> helfen.
>
> Und ich stehe irgendwie auf dem Schlaucht. Am bestem wäre vermutlich
> eine Art Funktion, die je nach Typ eine Zahl zurückgibt oder so?
>
> Für Hilfe oder einen Schubs in die richtige Richtung wäre ich dankbar.

Offensichtlich hast du eine Business-Anforderung, dass manche Werte
speziell sind. Das würde ich dann auch so in den Daten modellieren. Du
fügst einfach eine weitere Spalte hinzu (z.B. numerisch). Dann hast du z.B.

"text", "prio"
'hallo', 100
'welt', 80
'bahn', 60
'foo', 0

und

SELECT...
ORDER BY prio DESC, text ASC

Man kann die Zahlen natürlich auch anders vergeben. Mit entsprechender
Indizierung kann das dann auch recht effizient werden.

Ciao

robert

Re: VARCHAR-Spalte nach bestimmter Reihenfolge sortieren

am 05.06.2007 12:14:06 von Andreas Sakowski

"Holger Pollmann" schrieb
> Hallo,
>
> folgendes: ich habe eine MyISAM-Tabelle in einer MYSQL-5.0-Datenbank
> mit einer Spalte "typ", die in einer bestimmten Weise sortiert
> werden
> soll, nämlich in einer bestimmten Reihenfolge, die nicht
> alphabetisch
> ist. (Normalerweise würde ich ein ENUM deklarieren, aber hier müssen
> die Werte frei definierbar sein.)
>
> Am besten wäre es, wenn so etwas ginge wie
> Zuerst 'hallo',
> dann 'autobahn',
> dann 'welt',
> dann 'bahn',
> dann alles andere alphabetisch
>
[...]

Dann schreib es doch so hin:

mysql> create table bla ( typ varchar( 20 ) ) ;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into bla values ( 'sonne' ) , ( 'mond' )
, ( 'welt' ) , ( 'bahn' ) , ( 'autobahn' ) , ( 'hallo' ) ;
Query OK, 6 rows affected (0.01 sec)
Records: 6 Duplicates: 0 Warnings: 0

mysql> select * from bla ;
+----------+
| typ |
+----------+
| sonne |
| mond |
| welt |
| bahn |
| autobahn |
| hallo |
+----------+
6 rows in set (0.00 sec)

mysql> select typ from bla order by
case typ when 'hallo' then 1
when 'autobahn' then 2
when 'welt' then 3
when 'bahn' then 4
else typ end ;
+----------+
| typ |
+----------+
| hallo |
| autobahn |
| welt |
| bahn |
| mond |
| sonne |
+----------+
6 rows in set (0.00 sec)

Ich würde hier jedoch eine eigene Tabelle 'typen' anlegen und in
dieser das Attribut 'sortierung' mit aufnehmen und in der
Haupttabelle auf diese Tabelle verweisen. Dann kannst Du alles
zusammenjoinen und nach sortierung sortieren.

Gruß
Andreas

Re: VARCHAR-Spalte nach bestimmter Reihenfolge sortieren

am 05.06.2007 18:08:54 von Holger Pollmann

"Andreas Sakowski" schrieb:

> mysql> select typ from bla order by
> case typ when 'hallo' then 1
> when 'autobahn' then 2
> when 'welt' then 3
> when 'bahn' then 4
> else typ end ;

Genau so was habe ich gesucht, danke :-)

Kann man sowas eigentlich auch ine eine Procedure packen? Und wenn ja,
wie benutzt man die? Hatte mit Procedures bisher noch nix am Hut, aber
wenn ich schon MySQL 5 benutze...

> Ich würde hier jedoch eine eigene Tabelle 'typen' anlegen und in
> dieser das Attribut 'sortierung' mit aufnehmen und in der
> Haupttabelle auf diese Tabelle verweisen. Dann kannst Du alles
> zusammenjoinen und nach sortierung sortieren.

Sowas wie

CREATE TABLE bar
(typ VARCHAR(250) NOT NULL,
sortierung INT NOT NULL,
PRIMARY KEY (typ),
KEY (sortierung)
);

INSERT INTO bar VALUES ('hallo', '1'), ('autobahn', '2') ...

SELECT foo.name,foo.typ,bar.sortierung FROM foo,bar
WHERE foo.typ=bar.typ ORDER by bar.sortierung

?

Sorry, Joins sind nicht meine Stärke; generell sind meine SQL-Fähigkeiten
eher bescheiden...

--
( ROT-13 if you want to email me directly: uvuc@ervzjrexre.qr )
"Sie tragen Trauer? Der Untergang der DDR?" - "Nein, Leni Riefenstahl.
Der Führer hat sie zu sich genommen." -- Abschiedsshow Scheibenwischer,
02.10.2003

Re: VARCHAR-Spalte nach bestimmter Reihenfolge sortieren

am 06.06.2007 11:50:58 von Andreas Sakowski

"Holger Pollmann" schrieb im Newsbeitrag
news:5clg4mF313qhbU3@mid.individual.net...
> "Andreas Sakowski" schrieb:
>
>> mysql> select typ from bla order by
>> case typ when 'hallo' then 1
>> when 'autobahn' then 2
>> when 'welt' then 3
>> when 'bahn' then 4
>> else typ end ;
>
> Genau so was habe ich gesucht, danke :-)

Aber vielleicht nicht das, was Du brauchst. ;-)

> Kann man sowas eigentlich auch ine eine Procedure packen? Und wenn
> ja,
> wie benutzt man die? Hatte mit Procedures bisher noch nix am Hut,
> aber
> wenn ich schon MySQL 5 benutze...

Sicherlich. Allerdings bin ich bei mySQL mit Proceduren nicht so firm.
Aber
es gibt ja das Handbuch ;-)

>> Ich würde hier jedoch eine eigene Tabelle 'typen' anlegen und in
>> dieser das Attribut 'sortierung' mit aufnehmen und in der
>> Haupttabelle auf diese Tabelle verweisen. Dann kannst Du alles
>> zusammenjoinen und nach sortierung sortieren.
>
> Sowas wie
>
> CREATE TABLE bar
> (typ VARCHAR(250) NOT NULL,
> sortierung INT NOT NULL,
> PRIMARY KEY (typ),
> KEY (sortierung)
> );
>
> INSERT INTO bar VALUES ('hallo', '1'), ('autobahn', '2') ...
>
> SELECT foo.name,foo.typ,bar.sortierung FROM foo,bar
> WHERE foo.typ=bar.typ ORDER by bar.sortierung

So ungefähr. Ich würde es aber wie folgt machen:

mysql> create table typen (
id integer not null auto_increment primary key
, bezeichnung varchar( 50 )
, sortierung integer ) ;
Query OK, 0 rows affected (0.03 sec)

mysql> insert into typen ( bezeichnung , sortierung )
select typ , case typ when 'hallo' then 1 when 'autobahn' then 2
when 'welt' then 3 when 'bahn' then 4 else 0 end from bla ;
Query OK, 6 rows affected (0.00 sec)
Records: 6 Duplicates: 0 Warnings: 0

mysql> alter table bla add typenid integer references typen ;
Query OK, 6 rows affected (0.01 sec)
Records: 6 Duplicates: 0 Warnings: 0

mysql> update bla set typenid =
( select id from typen where bezeichnung = typ ) ;
Query OK, 6 rows affected (0.00 sec)
Rows matched: 6 Changed: 6 Warnings: 0

mysql> alter table bla
add foreign key ( typenid ) references typen( id ) ;
Query OK, 6 rows affected (0.05 sec)
Records: 6 Duplicates: 0 Warnings: 0

mysql> alter table bla modify typenid integer not null ;
Query OK, 6 rows affected (0.02 sec)
Records: 6 Duplicates: 0 Warnings: 0

mysql> select b.typ , t.id , t.bezeichnung , t.sortierung from bla b
left join typen t on t.id = b.typenid
order by t.sortierung , t.bezeichnung ;
+----------+------+-------------+------------+
| typ | id | bezeichnung | sortierung |
+----------+------+-------------+------------+
| mond | 2 | mond | 0 |
| sonne | 1 | sonne | 0 |
| hallo | 6 | hallo | 1 |
| autobahn | 5 | autobahn | 2 |
| welt | 3 | welt | 3 |
| bahn | 4 | bahn | 4 |
+----------+------+-------------+------------+
6 rows in set (0.00 sec)

Da Du was von myisam schriebst musst Du evtl. noch
ein alter table bla engine = innodb machen. Bei mir ist
innodb die Standardeinstellung. Sonst kannst Du in bla
bei typenid auch Werte eintragen, für die es in typen
dann keine Informationen gibt.

Dadurch das nun ein integer als Schlüssel existiert wird weniger
Speicherplatz verbraucht und die Verarbeitung geht schneller.
Durch das foreign key stellst Du sicher, das in bla keine unsinnigen
Werte drinnen stehen. In Deinem Beispiel wäre es nicht so schlimm,
da nur die Sortierung fehlen würde. Bei meiner Version hast Du dann
in Bla aber nur eine Nummer.

> Sorry, Joins sind nicht meine Stärke; generell sind meine
> SQL-Fähigkeiten
> eher bescheiden...

Dafür lese ich Dich in D.S.R.* recht gerne :-)

Gruß
Andreas