SQL Lite Abfrage

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Padidem
User
Beiträge: 63
Registriert: Donnerstag 8. Januar 2015, 14:52

zunächst habe ich zwei listen mit den absoluten Einwohnerzahlen:

sum_laender
Out[18]: [(64556818,)]

sum_migration
Out[19]: [(80613,)]

wie kann ich die Differenz dieser Listen bilden indem ich eine neue Liste mit eben dieser Differenz schreibe?
Sirius3
User
Beiträge: 18216
Registriert: Sonntag 21. Oktober 2012, 17:20

@Padidem: Summe ist eine Aggregationsfunktion und solange Du kein GROUP BY hast, liefert Dir das immer nur einen Datensatz. Statt eines fetchall brauchst Du also nur ein fetchone. Dann ist ein Datensatz ein Tuple mit allen Spaltenwerten, auch wenn es nur eine Spalte gibt.
Also statt mit Listen rechnen zu wollen, die logisch nicht existieren und mit Tupeln, deren Summenbildung meist sinnlos ist, solltest Du Dir den Wert, der Dich interessiert aus dieser Struktur herausholen und mit dem dann rechnen.
Oder soll die Rechnung von der Datenbank erledigt werden?
Padidem
User
Beiträge: 63
Registriert: Donnerstag 8. Januar 2015, 14:52

So lautet die Aufgabe:
:D

Produzieren sie eine Abfrage, die folgende Elemente enthält:
- Das Stimmgewicht des jeweiligen Landes;
- Die absolute Differenz der Einwohnerzahl in der Tabelle laender info und der Einwohnerzahl(
gesamt) in der Tabelle migrationshintergrund 2013; Hinweis: SQLite Funktionen
- Prozentualer Anteil der Personen mit Migrationshintergrund an der Gesamtbevölkerung (Tabelle:
migrationshintergrund 2013);
- Eingegrenzt auf diejenigen Läander, die mehr als 200 Einwohner pro km2 aber nicht mehr als 2000
haben;
Padidem
User
Beiträge: 63
Registriert: Donnerstag 8. Januar 2015, 14:52

habe folgende Einzelabfragen erzeugt:

1. Stimmgewicht des jeweiligen Landes:

Code: Alles auswählen

cursor.execute('''SELECT stimmgewicht,land FROM laender_info ''').fetchall()
2. Differenz:

Code: Alles auswählen

cursor.execute('''SELECT sum(insgesamt) FROM migrationshintergrund_2013''').fetchall() 
cursor.execute('''SELECT sum (einwohner_km2 * flaeche) FROM laender_info''').fetchall() 
Absolute Differenz: 64556818 – 80613

3. prozentualer Anteil:

Code: Alles auswählen

cursor.execute('''SELECT sum (insgesamt)  FROM migrationshintergrund_2013''').fetchall()
cursor.execute('''SELECT sum (mit_mh)  FROM migrationshintergrund_2013''').fetchall()

Code: Alles auswählen

anteil =[float (16538) / 80613]
4. Eingrenzung:

Code: Alles auswählen

cursor.execute('''SELECT land FROM laender_info WHERE einwohner_km2 BETWEEN 200 AND 2000''').fetchall()

wie kann ich die Einzelabfragen nun zu einer einzigen (kombinierten) Abfrage zusammenfassen???
Sirius3
User
Beiträge: 18216
Registriert: Sonntag 21. Oktober 2012, 17:20

@Padidem: Aufgabe 2 ist glaube ich anders gemeint. Aufgabe 3 soll in der Datenbank gelöst werden und nicht in Python, und wie Du JOINs machst, ist doch hoffentlich schon behandelt worden.
Padidem
User
Beiträge: 63
Registriert: Donnerstag 8. Januar 2015, 14:52

und wie berechne ich den prozentualen Anteil in der Datenbank?
Sirius3
User
Beiträge: 18216
Registriert: Sonntag 21. Oktober 2012, 17:20

genauso wie außerhalb
Padidem
User
Beiträge: 63
Registriert: Donnerstag 8. Januar 2015, 14:52

@ Sirius3: In etwa so:

Code: Alles auswählen

cursor.execute('''SELECT (sum (mit_mh)) / sum (insgesamt)  FROM migrationshintergrund_2013''').fetchall()
und wie kann ich mir dann eine Dezimalzahl ausgeben lassen?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Padidem hat geschrieben: und wie kann ich mir dann eine Dezimalzahl ausgeben lassen?
Wie meinst Du das? Meine Antwort auf eine so formulierte Frage wäre jetzt: Nutze die ``print``-Funktion :twisted: (Ich vermute das wolltest Du nicht wissen! Aber: was dann?)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Padidem
User
Beiträge: 63
Registriert: Donnerstag 8. Januar 2015, 14:52

also wenn ich den Befehl ausführe bekomme ich als Ergebnis:

Code: Alles auswählen

Out[41]: [(0,)]
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Schau Dir mal meine Tipps hier an: http://www.python-forum.de/viewtopic.ph ... 00#p270000

Offenbar kommt als Ergebnis da 0 raus. Sofern es nur *ein* Ergebnis geben kann, solltest Du auch ``fetchone()`` nutzen statt ``fetchall`` - ist Dir iirc auch schon mal gesagt worden. Dann hast Du nur ein Tupel und keine äußere Liste...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Padidem
User
Beiträge: 63
Registriert: Donnerstag 8. Januar 2015, 14:52

aber 16538 / 80613 muss doch eine Dezimalzahl ergeben und nicht 0...


Könnte ich die Abfragen auch über .executescript verbinden?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Padidem hat geschrieben:aber 16538 / 80613 muss doch eine Dezimalzahl ergeben und nicht 0...
Das ist vom Zahlentyp abhängig! In Python wird ab Version 3.x standardmäßig bei der Division von Integern ein ``float`` zurückgegeben. Man kann aber auch über den ``//``-Operator eine ganzzahliges Ergebnis berechnen:

Code: Alles auswählen

>>> 16538 / 80613
0.20515301502239092
>>> 16538 // 80613
0
Ich weiß nicht aus dem Kopf, wie SQL so etwas behandelt. Daher ja auch mein Tipp: Baue die Query Schritt für Schritt in einer Shell auf und nicht in Python. Das geht schneller und Du kannst Dir ja auch zusätzlich die Zahlenwerte noch ausgeben lassen. Evtl. wird da gar nicht 16538 / 80613 gerechnet, sondern 0 / 80613 ;-)
Padidem hat geschrieben: Könnte ich die Abfragen auch über .executescript verbinden?
Was willst Du denn damit erreichen?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Sirius3
User
Beiträge: 18216
Registriert: Sonntag 21. Oktober 2012, 17:20

@Padidem: Du mußt halt die Integer-Werte vor dem Teilen in Decimalzahlen umwandeln.
Bei SQL macht man das üblicherweise über die cast-Funktion:

Code: Alles auswählen

SELECT cast(16538 as float)
@Hyperion: auch wenn die sum-Funktion und noch so einiges andere das Gegenteil vermuten lassen, es soll zum Schluß pro Bundesland eine Zeile entstehen.
Padidem
User
Beiträge: 63
Registriert: Donnerstag 8. Januar 2015, 14:52

@ Hyperion: leider müssen wir alle Aufgaben über Python erledigen
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Padidem hat geschrieben:@ Hyperion: leider müssen wir alle Aufgaben über Python erledigen
Das bedeutet aber doch nicht, dass man die Query erst einmal *extern* in dem dafür vorgesehenem Werkzeug erstellt und anschließend in das Python-Script übernimmt‽

Offenbar kommt nicht das Ergebnis heraus, was Du erwartest. Also musst Du forschen, woran das liegt bzw. was wirklich passiert. Das macht man nun einmal in einer SQL-Shell. Wenn Du dann die fertige Query hast, kopierst Du sie heraus und fügst sie im Quellcode ein. Wo ist da ein Widerspruch zur Aufgabenstellung?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Padidem
User
Beiträge: 63
Registriert: Donnerstag 8. Januar 2015, 14:52

ich dachte mit dem executescript könnte man auch die einzelabfragen zu einer zusammenfassen
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Padidem hat geschrieben:ich dachte mit dem executescript könnte man auch die einzelabfragen zu einer zusammenfassen
Was denn für Einzelabfragen?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Padidem
User
Beiträge: 63
Registriert: Donnerstag 8. Januar 2015, 14:52

also die Einzelabfragen aus der Aufgabenstellung:

Stimmgewicht

Differenz der Einwohnerzahlen etc.
BlackJack

@Padidem: Die Aufgabenstellung spricht doch aber von *einer* Abfrage. Die einzelnen Punkte/Spiegelstriche in der Aufgabenstellung können ja schon deswegen nicht als Einzelabfragen gemeint sein weil der letzte Punkt gar nicht als solche umgesetzt werden kann sondern eine allgemeine Einschränkung des Ergebnisses darstellt.

Wie Hyperion schon sagte, solltest Du diese Abfrage in einem geeignetem Programm entwickeln und testen. Da ist nichts dynamisches drin, also ist das was Python zu dieser Aufgabe beiträgt nur *eine* SQL-Abfrage abzusetzen und die Datensätze auszugeben die dabei heraus kommen.
Antworten