Seite 1 von 1

MySQL Abfrage mit SELECT ... WHERE ... IN ()

Verfasst: Freitag 20. Mai 2011, 07:58
von HugoB
Hallo,

ich hole mir aus einer MySQL Datenbank eine Liste mit 1-n IDs:

Code: Alles auswählen

cursor.execute ("""SELECT DocType_ID FROM DocType WHERE DocType_Token = %s""", (TypeShort))
TypeIDs = cursor.fetchall()
Anschließend habe ich z. B.

Code: Alles auswählen

TypeIDs = ((1L,), (3L,))
Jetzt muß ich in einer zweiten Abfrage die Anzahl der Einträge aus einer anderen Tabelle holen, die einen der Werte haben. Über einen "SELECT ... WHERE ... IN ()" ist das kein Problem. Mein Ansatz war:

Code: Alles auswählen

TypeID = [ ]
    for id in TypeIDs:
        TypeIDList.extend(id)

cursor.execute ("""SELECT COUNT(Key_Count) FROM Document WHERE Type IN (%s)"""  , (TypeIDList))
aber das liefert mir nur:
(1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '[1L, 3L])' at line 1")
da der Befehl umgewandelt wird zu
SELECT COUNT(Key_Count) FROM Document WHERE Type IN ([1L, 3L])

Wie muß ich es richtig machen?
Und: Geht es nicht auch ohne, daß ich die Rückgabe des ersten SELECTS nochmal über eine For-Schleife umkoche (sicher gehts :-))

Re: MySQL Abfrage mit SELECT ... WHERE ... IN ()

Verfasst: Freitag 20. Mai 2011, 08:42
von BlackJack
@HugoB: Du musst die SQL-Anweisung dynamisch erstellen, so das für jedes Argument aus der Liste ein Platzhalter da steht. Also bei zwei IDs zum Beispiel "… IN (%s, %s)".

Deine Liste würde ich übrigens mit einer "list comprehension" aufbauen: ``type_ids = [row[0] for row in cursor.fetchall()]``

Re: MySQL Abfrage mit SELECT ... WHERE ... IN ()

Verfasst: Freitag 20. Mai 2011, 08:47
von Hyperion
Du könntest auch die komplette erste Query als Subquery in den `IN` Teil der zweiten einbauen. Damit überlässt Du dem RDBMS die Optimierung und sparst Dir den ganzen Aufwand.

Re: MySQL Abfrage mit SELECT ... WHERE ... IN ()

Verfasst: Freitag 20. Mai 2011, 08:54
von HugoB
BlackJack hat geschrieben:@HugoB: Du musst die SQL-Anweisung dynamisch erstellen, so das für jedes Argument aus der Liste ein Platzhalter da steht. Also bei zwei IDs zum Beispiel "… IN (%s, %s)".
Ernsthaft? Das scheint mir sehr umständlich. Ich hatte gehofft, daß mir Python hier die Arbeit abnimmt und ich nicht erst alles selbst zusammenbasteln muß. :-(

Aber vielen Dank für die Infos.

Re: MySQL Abfrage mit SELECT ... WHERE ... IN ()

Verfasst: Freitag 20. Mai 2011, 09:03
von HugoB
Hyperion hat geschrieben:Du könntest auch die komplette erste Query als Subquery in den `IN` Teil der zweiten einbauen. Damit überlässt Du dem RDBMS die Optimierung und sparst Dir den ganzen Aufwand.
Stimmt. Das ist eine super Idee. Vielen Dank. Und gleich noch Code eingespart. :-)


So hats funktioniert:

Code: Alles auswählen

cursor.execute ("""SELECT COUNT(Key_Count) FROM Document WHERE Type IN (SELECT DocType_ID FROM DocType WHERE DocType_Token = "%s")""" % (TypeShort))

Re: MySQL Abfrage mit SELECT ... WHERE ... IN ()

Verfasst: Samstag 21. Mai 2011, 15:21
von microkernel
HugoB hat geschrieben:

Code: Alles auswählen

cursor.execute ("""SELECT COUNT(Key_Count) FROM Document WHERE Type IN (SELECT DocType_ID FROM DocType WHERE DocType_Token = "%s")""" % (TypeShort))
Vielleicht sollte man jetzt noch sagen, dass folgende Variante sicherer wäre:

Code: Alles auswählen

cursor.execute ("""SELECT COUNT(Key_Count) FROM Document WHERE Type IN (SELECT DocType_ID FROM DocType WHERE DocType_Token = %s)""", (TypeShort,) )