Die länge einer SQL Datenbank anzeigen lassen

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
McAce
User
Beiträge: 32
Registriert: Dienstag 20. April 2010, 14:01

@sparrow deine Lösung sieht ziemlich gut aus leider bekomme ich das nicht in SQLite umgesetzet,
mache erst einmal eine Pause vielleicht hilft das ;-)

McAce
Benutzeravatar
sparrow
User
Beiträge: 4505
Registriert: Freitag 17. April 2009, 10:28

Das Problem: sqlite3 kann nicht 2 Spalten aus Subqueries.

Mit || verbindet man den Inhalt zweier Felder. Also bauen wir uns die Rückgabe entsprechend zussammen.
Auf meiner Beispieltabelle müsste also folgendes funktionieren:

Code: Alles auswählen

DELETE FROM testt WHERE name || dat NOT IN (SELECT name || MAX(dat) FROM testt GROUP BY name)
Ist ungetestet, sollte aber tun.

Falls du Fragen hast, heraus damit.

Gruß
sparrow
BlackJack

@Rainier: Das ist AFAIK kein Standard-SQL und es ist ja auch keine Zeilennummer sondern eben eine ID. Am Anfang war die Vorgabe ja noch eine zufällige Zeile über die "Zeilennummer" zu löschen.
Benutzeravatar
sparrow
User
Beiträge: 4505
Registriert: Freitag 17. April 2009, 10:28

Code: Alles auswählen

import sqlite3

con = sqlite3.connect(':memory:')
cursor = con.cursor()

cursor.execute("CREATE TABLE test (name VARCHAR, dat DATE)")
cursor.execute("INSERT INTO test (name, dat) VALUES ('a', date('2011-02-15'))")
cursor.execute("INSERT INTO test (name, dat) VALUES ('a', date('2011-02-20'))")
cursor.execute("INSERT INTO test (name, dat) VALUES ('a', date('2011-04-11'))")
cursor.execute("INSERT INTO test (name, dat) VALUES ('v', date('2011-01-08'))")
cursor.execute("INSERT INTO test (name, dat) VALUES ('v', date('2011-04-16'))")
cursor.execute("INSERT INTO test (name, dat) VALUES ('v', date('2011-07-18'))")
cursor.execute("INSERT INTO test (name, dat) VALUES ('b', date('2011-02-01'))")
cursor.execute("INSERT INTO test (name, dat) VALUES ('b', date('2011-02-03'))")
cursor.execute("INSERT INTO test (name, dat) VALUES ('l', date('2011-02-04'))")
cursor.execute("INSERT INTO test (name, dat) VALUES ('m', date('2011-02-05'))")
cursor.execute("INSERT INTO test (name, dat) VALUES ('m', date('2011-02-06'))")

print "Vorher:"
for t in cursor.execute("SELECT * FROM test"): print t

print "----"

deletequery = "DELETE FROM test WHERE name || dat NOT IN " \
              "(SELECT name || MAX(dat) FROM test GROUP BY name)"
cursor.execute(deletequery)

print "Nachher:"
for t in cursor.execute("SELECT * FROM test"): print t

cursor.close()
con.close()
McAce
User
Beiträge: 32
Registriert: Dienstag 20. April 2010, 14:01

Vielen Dank für den Hinweis, jetzt klappt es.
McAce
User
Beiträge: 32
Registriert: Dienstag 20. April 2010, 14:01

Hi,

kann mich jetzt nach den Klausuren wieder damit beschäftigen ;-)

Ich kämpfe jetzt damit das ich anstelle des Datums jetzt eine Floatzahl habe (REAL).
Da || ja ein Stringkonkatenator ist kann ich die beiden Werte name und zahl ja nicht verknüpfen
wie bekomme ich das hin?

McAce
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

Typecasting? Kann sqlite sowas? Und wieso ist dein Datum jetzt vom Typ real?

Edit
http://www.sqlite.org/lang_expr.html
http://www.sqlite.org/c3ref/mprintf.html
Benutzeravatar
sparrow
User
Beiträge: 4505
Registriert: Freitag 17. April 2009, 10:28

Hast du es einfach mal probiert?
Mal ganz abgesehen davon, dass ich in dem vorherigen Code ja schon einen String und ein Datum mit || verbunden habe.
Das geht also nicht nur mit Strings.

Code: Alles auswählen

import sqlite3
import random

con = sqlite3.connect(':memory:')
cursor = con.cursor()

cursor.execute("CREATE TABLE test (n VARCHAR, d FLOAT)")
cursor.execute("INSERT INTO test (n, d) VALUES ('a', ?)", (random.random(),) )
cursor.execute("INSERT INTO test (n, d) VALUES ('a', ?)", (random.random(),) )
cursor.execute("INSERT INTO test (n, d) VALUES ('a', ?)", (random.random(),) )
cursor.execute("INSERT INTO test (n, d) VALUES ('v', ?)", (random.random(),) )
cursor.execute("INSERT INTO test (n, d) VALUES ('v', ?)", (random.random(),) )
cursor.execute("INSERT INTO test (n, d) VALUES ('v', ?)", (random.random(),) )
cursor.execute("INSERT INTO test (n, d) VALUES ('b', ?)", (random.random(),) )
cursor.execute("INSERT INTO test (n, d) VALUES ('b', ?)", (random.random(),) )
cursor.execute("INSERT INTO test (n, d) VALUES ('l', ?)", (random.random(),) )
cursor.execute("INSERT INTO test (n, d) VALUES ('m', ?)", (random.random(),) )
cursor.execute("INSERT INTO test (n, d) VALUES ('m', ?)", (random.random(),) )

print "Vorher:"
for t in cursor.execute("SELECT * FROM test"): print t

print "----"

deletequery = "DELETE FROM test WHERE n || d NOT IN " \
              "(SELECT n || MAX(d) FROM test GROUP BY n)"
cursor.execute(deletequery)

print "Nachher:"
for t in cursor.execute("SELECT * FROM test"): print t

cursor.close()
con.close()
Macht bei mir:

Code: Alles auswählen

Vorher:
(u'a', 0.06153580392253222)
(u'a', 0.17540563549178978)
(u'a', 0.6532116785416114)
(u'v', 0.7049099555607308)
(u'v', 0.0660415757282301)
(u'v', 0.5568942848148242)
(u'b', 0.7574893473574899)
(u'b', 0.8842254785434168)
(u'l', 0.5659690705623256)
(u'm', 0.2888894289300361)
(u'm', 0.07183194624757139)
----
Nachher:
(u'a', 0.6532116785416114)
(u'v', 0.7049099555607308)
(u'b', 0.8842254785434168)
(u'l', 0.5659690705623256)
(u'm', 0.2888894289300361)
Und das sieht verdächtig nach dem aus was du brauchst und geändert hab ich nichts, außer andere Date zu schreiben.
McAce
User
Beiträge: 32
Registriert: Dienstag 20. April 2010, 14:01

Das verstehe ich jetzt nicht, ich hatte das genauso probiert bis auf die Tatsache das ich anstelle von
FLOAT REAL geschrieben hatte.
Soweit ich weiß ist das doch die Angabe von Float Zahlen in SQLite oder liege ich da jetzt falsch?

Grüße

McAce
Benutzeravatar
sparrow
User
Beiträge: 4505
Registriert: Freitag 17. April 2009, 10:28

Ach, sqlite3 nimmt das eh nicht so ernst mit den Typen der Spalten.

Code: Alles auswählen

import sqlite3

con = sqlite3.connect(':memory:')
cur = con.cursor()

cur.execute("CREATE TABLE test (id INTEGER PRIMARY KEY, dat INTEGER)")
cur.execute('INSERT INTO test (dat) VALUES (?)', (2,))
cur.execute('INSERT INTO test (dat) VALUES (?)', (144,))
cur.execute('INSERT INTO test (dat) VALUES (?)', (3.144,))
cur.execute('INSERT INTO test (dat) VALUES (?)', ('KEKS',))

print cur.execute("SELECT * FROM test").fetchall()

cur.close()
con.close()

Code: Alles auswählen

[(1, 2), (2, 144), (3, 3.144), (4, u'KEKS')]
Postgresql oder mySQL würden hier natürlich Alarm geben. Immerhin soll in ein Feld für Ganzzahlen ein String oder eine Fließkommazahl geschrieben werden. sqlite ist das egal, der nimmt halt das was kommt.

Gruß
Sparrow
McAce
User
Beiträge: 32
Registriert: Dienstag 20. April 2010, 14:01

merkwürdig, ich glaube da setze ich mich noch mal vor und suche mal warum das bei
mir nicht geklappt hat.

Vielen Dank für den Tipp

McAce
Antworten