Sortierung mit Hindernissen

Sortierung mit Hindernissen

am 03.10.2006 11:06:44 von Torsten Grossmann

Hallo allerseits,

ich moechte sortierte Ergebnisse so ausgeben, dass neben der
Sortierung z.B. nach Datum, ein nicht immer vorhandener weiterer Wert
zum tragen kommt. Die beiden Sortierungskriterien sind dabei
gleichwertig, ein *order by eins or zwei * sozusagen ;)))

Im Prinzip so:

datum, position
2001,0
2002,7
2003,0
2004,2

Neben der Datumsortierung sollte nun 2004 immer an 2ter Position
stehen usw.
Ehrlich gesagt, ich habe nicht einmal einen Ansatz :(( Ich moechte es
auch nicht ueber die scriptsprache loesen, sql sollte es schon sein.

Liebe Gruesse

Torsten

Re: Sortierung mit Hindernissen

am 03.10.2006 11:35:20 von Andreas Kretschmer

Andreas
--
q: why do so many people take an instant dislike to mysql?
a: it saves time (oicu in #postgresql)
Explaining the concept of referential integrity to a mysql user is like
explaining condoms to a catholic (Shadda in #postgresql)

Re: Sortierung mit Hindernissen

am 03.10.2006 12:08:30 von Kris

Torsten Grossmann wrote:
> ich moechte sortierte Ergebnisse so ausgeben, dass neben der
> Sortierung z.B. nach Datum, ein nicht immer vorhandener weiterer Wert
> zum tragen kommt. Die beiden Sortierungskriterien sind dabei
> gleichwertig, ein *order by eins or zwei * sozusagen ;)))

Deine Formulierungen sind unklar. Bitte beschreibe Dein Sortierkriterium als
Vergleichsfunktion.

Du kannst nach einer beliebigen virtuellen Spalte sortieren. Beispiel:

root@localhost [kris]> create table t ( id1 integer unsigned not null, id2
integer unsigned not null );
Query OK, 0 rows affected (0.00 sec)

root@localhost [kris]> insert into t ( id1, id2) values ( 2001, 0), (2002,
7), (2003, 0), (2004, 2);
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
root@localhost [kris]> select *, if (id2>0, id2, id1) as c from t order by
c;
+------+-----+------+
| id1 | id2 | c |
+------+-----+------+
| 2004 | 2 | 2 |
| 2002 | 7 | 7 |
| 2001 | 0 | 2001 |
| 2003 | 0 | 2003 |
+------+-----+------+
4 rows in set (0.00 sec)

Wenn Du c hier als geeignete Funktion definierst, wird SQL Dir das passend
sortieren.

Kris

Re: Sortierung mit Hindernissen

am 03.10.2006 18:36:34 von Torsten Grossmann

Kristian Köhntopp schrieb:

Hallo allerseits,

>Deine Formulierungen sind unklar. Bitte beschreibe Dein Sortierkriterium als
>Vergleichsfunktion.

hmm, diesen Ansatz wollte ich nicht hier posten ;)) Gut, ein:

$cnt = select count(id) from table;

select * if(pos<>0, pos,$cnt-id+1.1) as posid
from table order by posid asc;

wuerde die Tabelle

id,dat, pos
1, 2001, 0
2, 2002, 0
3, 2003, 0
4, 2004, 0...
18,1999, 2

in etwa so ausgeben

posid, dat
1.1, 2004
2, 1999
2.1, 2003
3.1, 2002
4.1, 2001

was das gewuenschte Ergebnis waere, allerdings nur bis zum ersten
delete.

Im Prinzip soll schon ordentlich nach Datum sortiert werden.
Unabhängig von Neueintraegen oder Loeschungen moechte ich aber einige
Datensaetze an fester Position ausgeben.

>select *, if (id2>0, id2, id1) as c from t order by

hier hast du angenommen, dass mir id2 zum sortieren fehlt, sorry fuer
die unklare Formulierung, hoffe oben ist besser gelungen :) Geht auch
an Andreas nebenan.

Gruss Torsten

Re: Sortierung mit Hindernissen

am 04.10.2006 20:37:26 von Kris

Torsten Grossmann wrote:
> $cnt = select count(id) from table;
>
> select * if(pos<>0, pos,$cnt-id+1.1) as posid
> from table order by posid asc;
>
> wuerde die Tabelle
>
> id,dat, pos
> 1, 2001, 0
> 2, 2002, 0
> 3, 2003, 0
> 4, 2004, 0...
> 18,1999, 2
>
> in etwa so ausgeben
>
> posid, dat
> 1.1, 2004
> 2, 1999
> 2.1, 2003
> 3.1, 2002
> 4.1, 2001
>
> was das gewuenschte Ergebnis waere, allerdings nur bis zum ersten
> delete.

Ok, dann werden wir mal ein wenig prozedural^Wbrachial. Sensible Naturen
halten sich also die Augen zu - und dem Rest sei
http://bugs.mysql.com/bug.php?id=16705 ans Herz gelegt. Nicht daß noch
jemand glaubt, das sei in irgendeiner Weise legal, was ich hier tue.

Es funktioniert bloß.


root@localhost [kris]> create table t ( id integer unsigned not null, dat
integer unsigned not null, pos integer unsigned not null );
Query OK, 0 rows affected (0.01 sec)

root@localhost [kris]> insert into t values (1, 2001, 0), (2, 2002, 0), (3,
2003, 0), (4, 2004, 0), (18, 1999, 2);
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0

root@localhost [kris]> set @a = 0;
Query OK, 0 rows affected (0.00 sec)

root@localhost [kris]> select @a := @a +1 as a, id from t;
+------+----+
| a | id |
+------+----+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 18 |
+------+----+
5 rows in set (0.00 sec)

Das ist so schön, daß kann man gleich mal mißbrauchen:

root@localhost [kris]> set @a=0; select * from ( select @a := @a +1 as a,
dat, pos, if (pos<>0, pos, @a+0.5) as o from t ) as s order by s.o;
Query OK, 0 rows affected (0.00 sec)

+------+------+-----+------+
| a | dat | pos | o |
+------+------+-----+------+
| 1 | 2001 | 0 | 1.5 |
| 5 | 1999 | 2 | 2.0 |
| 2 | 2002 | 0 | 2.5 |
| 3 | 2003 | 0 | 3.5 |
| 4 | 2004 | 0 | 4.5 |
+------+------+-----+------+
5 rows in set (0.00 sec)

Und weil wir das a gar nicht sehen wollen, räumen wir das auf zu

root@localhost [kris]> set @a=0; select s.o, s.id, s.dat from ( select @a :=
@a +1 as a, id, dat, pos, if (pos<>0, pos, @a+0.5) as o from t ) as s order
by s.o;
Query OK, 0 rows affected (0.00 sec)

+------+----+------+
| o | id | dat |
+------+----+------+
| 1.5 | 1 | 2001 |
| 2.0 | 18 | 1999 |
| 2.5 | 2 | 2002 |
| 3.5 | 3 | 2003 |
| 4.5 | 4 | 2004 |
+------+----+------+
5 rows in set (0.00 sec)


Kris