Schrift
[thread]12846[/thread]

MySQL :: Brauche Denkanstoß

Leser: 3


<< >> 9 Einträge, 1 Seite
MartinR
 2008-11-30 16:06
#116743 #116743
User since
2004-06-17
305 Artikel
BenutzerIn
[default_avatar]
Ich hangle mich, stark vereinfacht wie folgt, seitenweise durch eine Tabelle mit Artikeln wobei je Seite 10 ($artikel_je_seite) Artikel angezeigt werden. In $start steht dabei quasi die Seitenzahl.
Code: (dl )
1
2
3
4
SELECT * 
FROM artikel
ORDER BY irgendwas
LIMIT $start , $artikel_je_seite

Nun wird z.B auf der dritten Seite der Artikel xy gezeigt, da er lt. "order by" ganz einfach an 23ter Stelle kommt.

Soweit so gut. Nun aber mal umgekehrt. Wenn ich nun als Ausgangsbasis den Artikel xy habe, wie kann ich dann darauf schließen auf welcher Seite er erscheinen wird, also an welcher Stelle er im select steht? Ich könnte natürlich einfach ein select über die ganze Tabelle machen und dann in einem Schleifenzähler alle gefundenen Datensätze durchlaufen bis der gesuchte Artikel gefunden wurde. Aber es müsste doch auch einfacher gehen, oder?
pktm
 2008-11-30 16:11
#116744 #116744
User since
2003-08-07
2921 Artikel
BenutzerIn
[Homepage]
user image
Kannst du eine partielle Ordnung über das irgendwas (aus der ORDER_BY-Klausel) erstellen?
Also kannst du die in eine Relation miteinander bringen, in der du die miteinnder vergleiche kannst?

Sowas wäre z.B. eine fortlaufende Artikelnummer. Wenn du die Artikel nach Artikelnummer aufsteigend sortierst, kannst du zählen, wieviele Artikel es bis zu einem egegebenen Punkt gibt, und daraus den Rückschluss ziehen, wieviele Seiten es gibt (wobei du da eventuell mit der *partiellen* Ordnung schon Probleme hast).

Ansonsten hangel ich mich gerade hier durch, eventuell ist da was für dich dabei.

Grüße, pktm
http://www.intergastro-service.de (mein erstes CMS :) )
MartinR
 2008-11-30 16:21
#116745 #116745
User since
2004-06-17
305 Artikel
BenutzerIn
[default_avatar]
Wird wohl nicht gehen, da das Sortierkriterium variabel sein sollte. Also mal nach Preis, mal nach ArtNr, mal nach Text oder was auch immer ...
murphy
 2008-11-30 19:42
#116747 #116747
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
Das Ordnen sollte nicht das Problem sein, da Du für die ursprüngliche Abfrage ja auch geordnet hast. Das kannst Du dann bei der "Positionsbestimmung" genauso machen. Du brauchst nur noch eine Möglichkeit, den Eintrag, dessen Listenposition Du haben willst, eindeutig zu identifizieren.

Wenn Du die Liste mit
[sql]SELECT * FROM artikel ORDER BY irgendwas LIMIT $start , $artikel_je_seite[/sql]
erstellst, kannst Du mit
[sql]SELECT count(*) FROM artikel WHERE irgendwas < $ref_irgendwas[/sql]
zählen, wieviele Einträge vor dem gewünschten kommen, nachdem Du den Wert von irgendwas für den gesuchten Artikel herausgefunden und in $ref_irgendwas gespeichert hast.
When C++ is your hammer, every problem looks like your thumb.
pktm
 2008-11-30 19:55
#116749 #116749
User since
2003-08-07
2921 Artikel
BenutzerIn
[Homepage]
user image
Ja, aber wer sagt denn, dass $ref_irgendwas und irgendwas eine Zahl ist, die in einer Reihenfolge steht. Wenn du z.B. nach Artikelname sortierst, hast du Buchstaben, und auf denen ist die Ordnung < eben nciht mehr definiert.
http://www.intergastro-service.de (mein erstes CMS :) )
murphy
 2008-11-30 19:59
#116751 #116751
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
@pktm: Hmm, ich dachte, alles was in ORDER BY stehen kann, hat auch einen definierten < Operator, oder zumindest einen definierten <= Operator. Aber vielleicht ist das auch nur bei PostgreSQL und SQLite so, was die Datenbanken sind, die ich am meisten verwende, oder es hat bisher einfach nur für alle Datentypen, mit denen ich es ausprobiert habe, funktioniert...
When C++ is your hammer, every problem looks like your thumb.
murphy
 2008-11-30 23:25
#116754 #116754
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
Nachtrag: Ich habe in der Dokumentation verschiedener Datenbanksysteme nachgelesen:

- Bei SQLite3 kann man wirklich alles miteinander per < oder <= vergleichen, im Zweifelsfall wird binär per memcmp verglichen, aber auf jeden Fall ist der Vergleich immer konsistent mit einer ORDER BY-Klausel. Man kann insbesondere nicht nur hinter ORDER BY sondern auch hinter jeden Ausdruck mit Vergleichsoperator eine COLLATE-Klausel setzen, um die Vergleichsfunktion explizit festzulegen.

- PostgreSQL kann mit ORDER BY alle Datentypen sortieren, für die eine B-Tree-Operatorklasse definiert ist. Man kann also einen benutzerdefinierten Datentyp erzeugen, auf dem < oder <= nicht oder inkonsistent mit der B-Tree-Operatorklasse definiert sind. Für alle eingebauten Datentypen gilt aber, dass sie sich entweder mit ORDER BY und < oder <= konsistent vergleichen lassen, oder gar nicht.

- Bei MySQL habe ich leider in der Dokumentation und mittels Google keine Informationen darüber gefunden, wie die Vergleiche genau funktionieren. Ein kurzes Experiment legt aber nahe, dass bei Stringvergleichen ähnlich wie bei SQLite3 auch hier eine Sortierreihenfolge angegeben werden kann und alle Datentypen, die man mit ORDER BY sortieren kann auch mit den Vegleichsoperatoren konsistent verglichen werden können.

Ich wage daher zu behaupten, dass man mit meinem Ansatz keine Probleme bekommen sollte, solange man immer gleiche Datentypen miteinander vergleicht. Wenn Konversionen zum Tragen kommen, was hier nicht der Fall sein dürfte, verhalten sich die verschiedenen Datenbanken wieder etwas weniger einheitlich.
When C++ is your hammer, every problem looks like your thumb.
pktm
 2008-12-01 00:34
#116755 #116755
User since
2003-08-07
2921 Artikel
BenutzerIn
[Homepage]
user image
Hm, das wäre interessant mal zu testen, aber ich habe gerade keine Zeit dafür ;-(
http://www.intergastro-service.de (mein erstes CMS :) )
MartinR
 2008-12-01 08:18
#116758 #116758
User since
2004-06-17
305 Artikel
BenutzerIn
[default_avatar]
Hallo und danke erst mal für die Antworten.

Also eine Abfrage etwa in der Art
Code: (dl )
SELECT * FROM orte WHERE ortsname < 'Köln'
scheint in dieser Tabelle
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CREATE TABLE `orte` (
`ortsname` varchar(50) NOT NULL default '',
KEY `ortsname` (`ortsname`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO `orte` VALUES ('Aachen');
INSERT INTO `orte` VALUES ('Berlin');
INSERT INTO `orte` VALUES ('Frankfurt');
INSERT INTO `orte` VALUES ('Hamburg');
INSERT INTO `orte` VALUES ('Hanover');
INSERT INTO `orte` VALUES ('Köln');
INSERT INTO `orte` VALUES ('München');
INSERT INTO `orte` VALUES ('Nürnberg');
INSERT INTO `orte` VALUES ('Stuttgart');
INSERT INTO `orte` VALUES ('Zwickau');
unter MySQL tatsächlich das gewünschte Ergebnis zu produzieren, nämlich
Code: (dl )
1
2
3
4
5
Aachen 
Berlin
Frankfurt
Hamburg
Hanover
und es funktioniert sogar sowas
Code: (dl )
SELECT * FROM orte WHERE ortsname > 'ha'
mit diesem Ergebnis
Code: (dl )
1
2
3
4
5
6
7
Hamburg 
Hanover
Köln
München
Nürnberg
Stuttgart
Zwickau
<< >> 9 Einträge, 1 Seite



View all threads created 2008-11-30 16:06.