Seite 1 von 1

SELECT Befehl gibt einen unerwarteten Resultat

Verfasst: Mittwoch 28. Juli 2021, 18:57
von omissoni
System:
Linuxmint 19.3
Python 3.7.10
Mysql Ver 14.14 Distrib 5.7.34

Von folgender Tabelle 'parts' möchte ich den höchsten 'NumberOfHoles' und den entsprechenden 'Reference' Wert, also 8 und B725 erfahren.

Code: Alles auswählen

+----+-----------+----------+---------+---------+---------------+-------------+-------------+-------+
| ID | Reference | PartName | MinArea | MaxArea | NumberOfHoles | MinDiameter | MaxDiameter | Count |
+----+-----------+----------+---------+---------+---------------+-------------+-------------+-------+
|  1 | W482      | Washer   |   29021 |   29300 |             4 |       204.7 |       207.4 |     3 |
|  2 | N154      | Mount    |   26600 |   26800 |             4 |         230 |         232 |     2 |
|  3 | B785      | Bolt     |    3900 |    4100 |             3 |        90.5 |          92 |     4 |
|  4 | W895      | Washer   |   35000 |   35100 |             7 |         127 |       128.5 |     4 |
|  5 | W811      | Missis   |   31000 |   32100 |             1 |         166 |         231 |     6 |
|  6 | B725      | Bolt     |   31900 |   41100 |             8 |       390.5 |         392 |     9 |
|  7 | Q312      | Missis   |    1265 |    1367 |             3 |        23.3 |        25.9 |    12 |
|  8 | Q322      | Bolt     |    3265 |    4367 |             5 |       233.3 |       235.9 |     2 |
+----+-----------+----------+---------+---------+---------------+-------------+-------------+-------+
Warum gibt mir folgender Code aber 8 und W482 aus? r1[1] ist immer W482 :-(

Code: Alles auswählen

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import mysql.connector

db = mysql.connector.connect(host ="localhost",
                             user='root',
                             password='nononomypasswdunreadable',
                             database='GUIcourse')
cursor=db.cursor()         
cursor.execute("SELECT MAX(NumberOfHoles), Reference from parts")
r1 = cursor.fetchone()
print(r1[0], r1[1]) 
db.close()

Re: SELECT Befehl gibt einen unerwarteten Resultat

Verfasst: Mittwoch 28. Juli 2021, 19:09
von __deets__
Weil du einfach nur eine Aggregation für eine Spalte machst. Aber ansonsten einfach die Zeilen in einer internen Reihenfolge ausgegeben werden. Statt Max solltest du einfach absteigend sortieren nach der Spalte, und dann bekommst du die gewünschte Zeile als erstes zurück.

Re: SELECT Befehl gibt einen unerwarteten Resultat

Verfasst: Mittwoch 28. Juli 2021, 19:46
von Sirius3
Was soll passieren, wenn mehrere Einträge 8 Holes haben?
Warum heißt `r1` `r1`? Warum nicht result, oder gleich `(max_number_of_holes, reference)`.

Re: SELECT Befehl gibt einen unerwarteten Resultat

Verfasst: Mittwoch 28. Juli 2021, 21:33
von omissoni
Sirius3 hat geschrieben: Mittwoch 28. Juli 2021, 19:46 Was soll passieren, wenn mehrere Einträge 8 Holes haben?
Warum heißt `r1` `r1`? Warum nicht result, oder gleich `(max_number_of_holes, reference)`.
Macht nichts wenn mehrere Produkte 8 Löcher haben. r1 weil ich es vom Kurs so übernommen habe. Aber result is lesbarer.

Re: SELECT Befehl gibt einen unerwarteten Resultat

Verfasst: Mittwoch 28. Juli 2021, 21:38
von omissoni
__deets__ hat geschrieben: Mittwoch 28. Juli 2021, 19:09 Weil du einfach nur eine Aggregation für eine Spalte machst. Aber ansonsten einfach die Zeilen in einer internen Reihenfolge ausgegeben werden. Statt Max solltest du einfach absteigend sortieren nach der Spalte, und dann bekommst du die gewünschte Zeile als erstes zurück.
Danke, das hat mich weitergebracht. Der code sieht jetzt so aus aber der "Maximum"-Teil geht nicht:

Code: Alles auswählen

cursor=db.cursor()  

# Minimum 
cursor.execute("SELECT  NumberOfHoles, Reference FROM parts ORDER BY Numberofholes")
result = cursor.fetchone()
print(result[0], result[1]) 

cursor2=db.cursor()  # hier erscheint die Fehlermeldung: self.handle_unread_result(prepared)

#Maximum
cursor2.execute("SELECT  NumberOfHoles, Reference  FROM parts ORDER BY Numberofholes DESC")
result = cursor2.fetchone()
print(result[0], result[1])

Re: SELECT Befehl gibt einen unerwarteten Resultat

Verfasst: Mittwoch 28. Juli 2021, 21:49
von __deets__
Was heißt geht nicht?

Re: SELECT Befehl gibt einen unerwarteten Resultat

Verfasst: Mittwoch 28. Juli 2021, 21:51
von Sirius3
Wenn Du nur ein Element brauchst, dann benutze LIMIT:

Code: Alles auswählen

cursor.execute("SELECT  NumberOfHoles, Reference FROM parts ORDER BY Numberofholes LIMIT 1")
number_of_holes, reference = cursor.fetchone()
print(number_of_holes, reference)

Re: SELECT Befehl gibt einen unerwarteten Resultat

Verfasst: Donnerstag 29. Juli 2021, 09:27
von DasIch
omissoni hat geschrieben: Mittwoch 28. Juli 2021, 18:57 Warum gibt mir folgender Code aber 8 und W482 aus? r1[1] ist immer W482 :-(
If ONLY_FULL_GROUP_BY is disabled, a MySQL extension to the standard SQL use of GROUP BY permits the select list, HAVING condition, or ORDER BY list to refer to nonaggregated columns even if the columns are not functionally dependent on GROUP BY columns. This causes MySQL to accept the preceding query. In this case, the server is free to choose any value from each group, so unless they are the same, the values chosen are nondeterministic, which is probably not what you want.
https://dev.mysql.com/doc/refman/5.7/en ... dling.html

Mit anderen Worten du solltest eigentlich einen Fehler bekommen aber weil deine MySQL Datenbank fragwürdig konfiguriert ist bekommst du Unsinn oder wie die MySQL Dokumentation so euphemistisch sagt "wahrscheinlich nicht was du willst".

Man beachte auch dass nondeterministic hier, __deets__ Aussage dass es basierend auf der internen Reihenfolge ist mag richtig sein ist aber nicht durch die Dokumentation garantiert, dementsprechend sollte man sich darauf nicht verlassen.

Re: SELECT Befehl gibt einen unerwarteten Resultat

Verfasst: Donnerstag 29. Juli 2021, 09:56
von __deets__
@DasIch ich hatte mich schon gewundert, warum das überhaupt ging. Aber meine SQL Zeiten liegen schon etwas zurück…

Re: SELECT Befehl gibt einen unerwarteten Resultat

Verfasst: Freitag 30. Juli 2021, 15:33
von omissoni
Danke allen für die wertvollen Vorschläge. Mit den Vorschlägen habe ich das gebastelt und dann das bekommen, was ich eigentlich wollte. Aber ich habe das schlecht kommuniziert . Ich wollte ,von eine nach einem Feld geordnete Liste nur der erster und letzter Datensatz.

ich hab es so erreicht:

Code: Alles auswählen

   
        cursor=db.cursor()                
        min_hls = "SELECT  NumberOfHoles, Reference  from parts order by Numberofholes"
        cursor .execute(min_hls)
        result = cursor .fetchone()
        
        #Minimum
        print (result[0], result[1])

        result = cursor.fetchall()
        result = result[len(result) - 1]

         #maximum
        print (result[0], result[1])
Danke/Thank you

Re: SELECT Befehl gibt einen unerwarteten Resultat

Verfasst: Freitag 30. Juli 2021, 17:23
von __blackjack__
@omissoni: `result` wird an viel zu viele verschiedene Werte mit unterschiedlichen Bedeutungen und Typen gebunden. Das ist verwirrend.

Ich würde da auch nicht erst `fetschone()` und dann `fetchall()` machen. Es macht nicht wirklich einen grossen Unterschied einfach nur `fetchall()` aufzurufen und davon dann das erste und letzte Element zu nehmen.

Wobei hier die Sonderfälle kein Ergebnis und nur ein Ergebnis nicht berücksichtigt werden vom Code!

Beim ``len(result) - 1`` ist das ``len(result)`` überflüssig.

Code: Alles auswählen

from contextlib import closing

...

        with closing(db.cursor()) as cursor:
            cursor.execute(
                "SELECT numberofholes, reference"
                " FROM parts"
                " ORDER BY numberofholes"
            )
            rows = cursor.fetchall()
            if len(rows) < 2:
                raise ValueError("less than two results for min and max")

            minimum, maximum = rows[0], rows[-1]
            print(minimum[0], minimum[1])
            print(maximum[0], maximum[1])