MySQL Anzahl der Zeilen einer Tabelle bis bestimmter Stelle

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
DingoDin
User
Beiträge: 4
Registriert: Samstag 22. Januar 2011, 12:25

Hallo,
ich habe folgendes Problem.

Eine MySQL Tabelle soll nach der Spalte "score" sortiert werden und dann möchte ich die Anzahl
der Zeilen bis zu der Zeile wo in der Spalte "playername" ein bestimmter name auftaucht.

Ich hoffe ich hab mich verständlich ausgedrückt :K

Es geht eigtl. darum das ich in einer Tabelle Spielerdaten abspeichere und durch das sortieren nach
Punkten soll sich die Platzierung des Spielers anhand der gezählten Zeilen ergeben.

Ich steh da jetzt irgendwie völlig auf dem Schlauch.

LG Dingo
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Was spricht dagegen, den Zählindex innerhalb von Python zu erstellen? Letztlich wäre eine solche Nummerierung streng genommen eh redundant, da sie sich durch die Punkte ja ergibt.

Ich weiß nicht, wie Du auf die DB zugreifst, aber per DB2 API sollte doch ein enumerate über die Rows möglich sein. Und bei SQLAlchemy und Co. dürfte das auch möglich sein.

Edit: Weil ich grad Lust zu hatte ;-)

Code: Alles auswählen

In [7]: import sqlite3

In [8]: con = sqlite3.connect(":memory:")

In [9]: cursor = con.cursor()

In [10]: cursor.execute("""
   ....: create table score (
   ....: name text,
   ....: points integer,
   ....: primary key(name)
   ....: )
   ....: """)
Out[10]: <sqlite3.Cursor object at 0x01092160>

In [11]: cursor.executemany("insert into score values (?, ?)",
   ....: [("chris", 120), ("alfi hartkor", 142), ("foobar", 50)])
Out[11]: <sqlite3.Cursor object at 0x01092160>

In [12]: res = cursor.execute("select name, points from score order by points")

In [13]: for index, row in enumerate(res):
   ....:     print index, row
   ....:
   ....:
0 (u'foobar', 50)
1 (u'chris', 120)
2 (u'alfi hartkor', 142)
Ok, die Sortierreiehnfolge muss halt wohl auf "desc" gestellt und beim enumerate am Schluss noch den Startindex auf 1 gesetzt werden.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
DingoDin
User
Beiträge: 4
Registriert: Samstag 22. Januar 2011, 12:25

Hyperion hat geschrieben:... Ich weiß nicht, wie Du auf die DB zugreifst, aber per DB2 API sollte doch ein enumerate über die Rows möglich sein. ...
Sry, ich hab grad erst vor zwei Tagen mit python angefangen.
Ich benutze das modul MySQLdb -> DB2 API

Okay, ich werd mir die Funktion enumerate() mal ansehen.

Wie genau meinst du das "enumerate über die Rows" ..?
Wäre es unverschämt nach einen kl. bsp. Code zu fragen ... :oops:
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

DingoDin hat geschrieben: Wie genau meinst du das "enumerate über die Rows" ..?
Wäre es unverschämt nach einen kl. bsp. Code zu fragen ... :oops:
Hast mein Beispiel wohl noch nicht gesehen ;-)

enumerate ist eine built-in Funktion in Python. Schau einfach mal in die Doku, da wird es gut erklärt :-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
DingoDin
User
Beiträge: 4
Registriert: Samstag 22. Januar 2011, 12:25

Alles klärchen ...
Ich habs ... Vielen Dank für die Hilfe.
Bei mir sieht es jetzt so aus.

Code: Alles auswählen

db = MySQLdb.connect("localhost","XXXX","XXXX","XXXX")
cursor = db.cursor()

cursor.execute('SELECT playername FROM players ORDER BY score DESC')
result = cursor.fetchall()

cursor.close()
db.close()

for index, row in enumerate(result):
	if row[0] == such_player:
		player_rang = index
Wobei "such_player" der Spieler ist nach dem gesucht wurde. Ich benötige ja den Rang nur von ihm.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Du solltest noch mal nachlesen, ob es eine gute Idee ist, den Cursor und die DB-Verbindung vor dem Auslesen zu schließen. Sinn eines Cursors ist es ja gerade, nicht sofort alle Daten zum Client zurückzuübertragen afair.

Man könnte das ganze auch funktional lösen:

Code: Alles auswählen

In [76]: from itertools import ifilter, izip, count

In [77]: from operator import itemgetter

In [78]: row = itemgetter(1)

In [79]: key = itemgetter(0)

In [80]: res = cursor.execute("select name, points from score order by points desc")

In [86]: index, player = ifilter(lambda data: key(row(data)) == "foobar" , izip(count(1), res)).next()

In [87]: index, player
Out[87]: (3, (u'foobar', 50))
:-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
DingoDin
User
Beiträge: 4
Registriert: Samstag 22. Januar 2011, 12:25

Danke, ich schau mir das auch nochmal an.
Beim kompl. Code hab ich den Cursor und die DB erst später geschlossen.

Ich werde den ganzen Code jetzt erstmal kompl. überarbeiten.
Soweit funktioniert zwar alles, sieht aber noch Quick & Dirty aus :oops:

Das ganze Script ist ja noch etwas komplexer.
Es stellt eine Verbindung zum GameServer her und filtert die für die Player Statistik
relevanten Daten und speichert diese in einer Datenbank.
Die Daten werden dann jedem Player über entsprechende Befehle über den InGameChat
zur Verfügung gestellt und werden im InGameChat eingeblendet.

Das ganze wird evtl. noch zu einem Vollwertigem AdminTool erweitert.

Ich mag python ... .. . :wink:
Antworten