Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Cross-Platform-Entwicklung (https://www.delphipraxis.net/91-cross-platform-entwicklung/)
-   -   iOS SQLite - Select mit mehreren Tabellen (https://www.delphipraxis.net/179558-sqlite-select-mit-mehreren-tabellen.html)

Crocotronic 15. Mär 2014 22:04

SQLite - Select mit mehreren Tabellen
 
Guten Abend,
vielleicht kann mir von euch jemand erklären, warum folgender Select-Befehl unter iOS nicht funktioniert:
Code:
SELECT s.teamA, count(t.recno) FROM spiel s, tor t WHERE s.recno = t.spielnr GROUP BY s.teamA
Müsste normalerweise funktionieren, unter iOS gibt es aber die Exception "Operation wird nicht unterstüzt" :pale:

Viele Grüße
Croco

jobo 16. Mär 2014 07:48

AW: SQLite - Select mit mehreren Tabellen
 
Keine Ahnung warum.
In solchen Fällen versuche ich, so klassisch wie möglich zu arbeiten. Also ausprobieren, ob eine möglichst konventionelle oder Standard-nahe Schreibweise hilft.
1. Aliase nutzen, fehlt beim Count Ausdruck
2. Join Notation verwenden (statt where)
3. Select Statement verschachteln, also ein (normal nicht benötigtes) 2. Select um das nicht funktionierende herumbauen, natürlich ohne weitere Bedingungen und so.

Alternativ die eigentliche Fehlerquelle eingrenzen, indem bestimmte Konstrukte systematisch entfernt werden, z.B. hier das Count. Das bedeutet, ein komplexes Stück Code / SQL so lange vereinfachen, bis man auf minimale Art den Fehler reproduzieren kann. So kann man wenigstens rausfinden, was funktioniert und wo man vielleicht workarrounds finden muss. Das reduzierte Code Fragment eignet sich auch prima für Nachfragen in Foren.

P.S.: 4. das Count(feldname) durch count(*) ersetzen

himitsu 16. Mär 2014 09:07

AW: SQLite - Select mit mehreren Tabellen
 
Zitat:

Zitat von jobo (Beitrag 1252120)
P.S.: 4. das Count(feldname) durch count(*) ersetzen

Kommt drauf an, was man zählen will.

SQL-Code:
SELECT count(*) AS Datensätze, count(Feld) AS NichtLeer FROM Tabelle


SQL-Code:
count(*)
zählt alle Datensätze und
SQL-Code:
count(Feld)
zählt nur mit, wenn etwas in "Feld" drin ist. (
SQL-Code:
Feld IS NOT NULL
)


Ich glaub das
SQL-Code:
GROUP BY
könnte man auch weglassen, da bestimmt schon über das Count gruppiert zusammengefasst wird und es sowieso nur noch das Feld "teamA" gibt, welches keine Aggregate-Function ist.

SQL-Code:
SELECT teamA, count(*)
FROM spiel
JOIN tor ON spiel.recno = spielnr
Mit einem LEFT JOIN würde man dann auch die Teams ohne Tore erwischen.
SQL-Code:
SELECT teamA, count(tor.recno)
FROM spiel
JOIN tor ON spiel.recno = spielnr

Furtbichler 16. Mär 2014 09:23

AW: SQLite - Select mit mehreren Tabellen
 
Nee, 'GROUP BY' muss immer da sein, wenn nicht über alles aggregiert wird. Ich verstehe nicht warum, aber man muss es angeben, obwohl die GROUP BY Klausel immer der Feldliste entspricht, die im SELECT angegeben ist, wenn man die Aggregatfunktionen weglässt.
Code:
SELECT <BlaFaselZeugs>
     , SUM(Foo)
     , COUNT(*)
     , AVG(Bar)
  FROM Tabelle
GROUP BY <BlaFaselZeugs>

Crocotronic 16. Mär 2014 14:13

AW: SQLite - Select mit mehreren Tabellen
 
Vielen Dank für die Tipps, funktioniert jetzt :thumb:
Code:
SELECT teamA, count(*)
FROM spiel
JOIN tor ON spiel.recno = spielnr GROUP BY teamA
Jetzt habe ich nur noch ein Problem mit dem Subselect. In meinem Fall muss ich etwas gruppieren und dann den Mittelwert aller Gruppen berechnen:
Code:
SELECT AVG(tmp) FROM (
                        SELECT table1.feld3, table2.feld5, (SUM(...)/COUNT(*))/10 AS tmp
                        FROM table1 JOIN table2 ON table1.fkey = table2.pkey
                        GROUP BY table1.feld3, table2.feld5
                      );
Das Beispiel ist zwar nicht gerade anschaulich, zeigt aber was ich machen will.
Hierbei bekomme ich wieder den Fehler, dass die Operation nicht unterstüzt wird.

mkinzler 16. Mär 2014 14:22

AW: SQLite - Select mit mehreren Tabellen
 
Ich kenne mich mit SqLite nicht so aus, versuch mal
SQL-Code:
 
SELECT
    AVG(s.tmp) as tmp
FROM
(         
    SELECT
        table1.feld3, table2.feld5, (SUM(...)/COUNT(*))/10 AS tmp
    FROM table1 
             JOIN table2 ON table1.fkey = table2.pkey
    GROUP BY
        table1.feld3, table2.feld5
    ) s;

Crocotronic 16. Mär 2014 15:25

AW: SQLite - Select mit mehreren Tabellen
 
Das ist es leider auch nicht :|

mkinzler 16. Mär 2014 15:32

AW: SQLite - Select mit mehreren Tabellen
 
Wenn SQLite immer ein Gruppierungsfeld haben will, dann geben wir es ihm halt
SQL-Code:
SELECT
    1 as Feld, AVG(s.tmp) as tmp
FROM
(
    SELECT
        table1.feld3, table2.feld5, (SUM(...)/COUNT(*))/10 AS tmp
    FROM table1
             JOIN table2 ON table1.fkey = table2.pkey
    GROUP BY
        table1.feld3, table2.feld5
    ) s
group by
  s.Feld;

Crocotronic 16. Mär 2014 15:48

AW: SQLite - Select mit mehreren Tabellen
 
Und immernoch wird die Exception "Operation wird nicht Unterstützt" ausgelöst :(

mkinzler 16. Mär 2014 15:55

AW: SQLite - Select mit mehreren Tabellen
 
Und wenn Du das Dummyfeld in die derived table verschiebst?

Crocotronic 16. Mär 2014 16:58

AW: SQLite - Select mit mehreren Tabellen
 
Irgendwie kommt es mir so vor, als wären Subqueries gar nicht möglich :?:

Furtbichler 17. Mär 2014 06:59

AW: SQLite - Select mit mehreren Tabellen
 
Zitat:

Zitat von Crocotronic (Beitrag 1252134)
In meinem Fall muss ich etwas gruppieren und dann den Mittelwert aller Gruppen berechnen:
Code:
SELECT AVG(tmp) FROM (...(SUM(...)/COUNT(*))... AS tmp);

Jedes Subselect benötigt einen Alias, also:
Code:
 SELECT .... from (select ... from ...) alias X
Dessenungeachtet ist das Mittelwertbilden von Mittelwerten eine Milchmädchenrechnung:
Auf der Insel Delfipractico befinden sich die Dörfer Villa-Vcl und Villa-Fmx.
Die 1000 Bewohner von Villa-Vcl verdienen im Durchschnitt 1 Euro (arme Bauern halt).
Die beiden Bewohner von Villa-Fmx verdienen beide jeweils 1000 Euro (sie vermarkten die bäuerlichen Erzeugnisse).
Der Durchschnittslohn auf der Insel Delfipractico beträgt also...
a: (1000 + 1) / 2 = 500,50 Euro?
b: (1000 x 1 + 2 x 1000) / 1002 = 2,99 Euro?
c: 1 Euro? (Median)

Ganz sicher nicht (a). Je nach konkreter Fragestellung eher (b) oder (c).

Das ändert natürlich nichts an der Problematik von Subselects, aber dein Beispiel verwirrt mich, und deshalb mein Einwand.

jobo 17. Mär 2014 07:19

AW: SQLite - Select mit mehreren Tabellen
 
Zitat:

Zitat von Crocotronic (Beitrag 1252160)
Irgendwie kommt es mir so vor, als wären Subqueries gar nicht möglich :?:

Mir kommt es so vor, als ob das ein sehr schwacher (Denk-)Ansatz ist.

Wer oder was hindert Dich eine einfache Subquery Abfrage zu testen?
Es ist doch offensichtlich so, dass iOS Doku zum Thema sqlite nicht sehr verfügbar ist. (was ich sehr seltsam finde- gibt es wenigstens sowas wie eine bekannte sqLite Version unter iOS?)
Außerdem gibt es scheinbar nicht viele Leute, die ein entsprechendes System am Start haben und solche Fragen nachvollziehen können.
Wie soll auf dieser Grundlage ein unvollständig angegebenes SQL Statement funktionsfähig gemacht werden?
Kannst Du aktuell sagen, welcher Teil des Statements überhaupt den Fehler verursacht?

Crocotronic 17. Mär 2014 13:20

AW: SQLite - Select mit mehreren Tabellen
 
Okay, pass auf:
Es soll eine Notenverwaltung + Rechner erstellt werden. Ich habe 3 Tabelle: Noten, Gewichtungen und Schulfächer. Die Tabelle Noten besteht aus den Fremdschlüsseln Subject , Weight und dem Attribut Grade(Float). Jetzt soll der Notenstand aller Fächer berechnet werde, also z.B.:
Code:
(Note1*Gewichtung1)+(Note4*Gewichtung1)+(Note6*Gewichtung1)/(Anzahl Noten Pro Gewichtung)+
(Note2*Gewichtung2)+(Note3*Gewichtung2)/(Anzahl Noten Pro Gewichtung)+...
Dazu folgende Abfrage:
SQL-Code:
SELECT SUM(tmp) FROM (
                      SELECT weights.weight, subjects.name, SUM(grades.grade*weights.weight)/COUNT(*))/100 AS tmp
                      FROM grades
                            JOIN subjects ON grades.subject = subjects.recno
                            JOIN weights ON grades.weight = weights.recno
                      GROUP BY weights.weight, subjects.name'
                       ) AS x;
Die Exception tritt auf, sobal ich das aüßer Select hinzufüge.

himitsu 17. Mär 2014 13:25

AW: SQLite - Select mit mehreren Tabellen
 
Zitat:

Zitat von Crocotronic (Beitrag 1252245)
SQL-Code:
SELECT SUM(tmp) FROM (
                      SELECT weights.weight, subjects.name, SUM(grades.grade*weights.weight)/COUNT(*))/100 AS tmp
                      FROM grades
                            JOIN subjects ON grades.subject = subjects.recno
                            JOIN weights ON grades.weight = weights.recno
                      GROUP BY weights.weight, subjects.name'
                       ) AS x;

Ist das jetzt der unveränderte Original-Code?

Dann ist das ' schonmal falsch.

mkinzler 17. Mär 2014 13:34

AW: SQLite - Select mit mehreren Tabellen
 
Zudem sind alle Verbesserungen dieses Threads nicht umgesetzt!

Ich würde auch konsequent Aliase verwenden. Die Joinbedingungen sind auch vertauscht.

SQL-Code:
SELECT
  1 as Feld,
  SUM(x.tmp) as tmp
FROM
  (
      SELECT
          w.weight, s.name, SUM(g.grade*w.weight)/COUNT(*))/100 AS tmp
      FROM
          grades g
              JOIN subjects s ON s.recno = g.subject
              JOIN weights ON w.recno = g.weight
      GROUP BY
          w.weight, s.name
) x
GROUP BY
  x.Feld;

Furtbichler 17. Mär 2014 13:40

AW: SQLite - Select mit mehreren Tabellen
 
Hmmm. Scheint so, als ob SQLite wirklich 'SQL light' ist.

Übrigens: Der gewichtete Mittelwert berechnet sich aber eher so:
(Note1*g1 + Note2*g2...NoteN*gN)/(g1+g2+...gN)

Beispiel:
Noten (1,2,3) Gewichte (100,5,1) = (100*1 + 2*5 + 3*1) / (100+5+1) = 113/106 = 1,1
Bei deiner Formel käme aber 113/3 = 39 heraus.

Ich denke, man könnte so zum Ziel kommen

Code:
SELECT SUM(grades.grade*weights.weight)/sum(weights.weight) AS averageGrade
  FROM grades
       JOIN subjects ON grades.subject = subjects.recno
       JOIN weights ON grades.weight = weights.recno

Crocotronic 17. Mär 2014 14:19

AW: SQLite - Select mit mehreren Tabellen
 
Zitat:

Zitat von mkinzler (Beitrag 1252250)
SQL-Code:
SELECT
  1 as Feld,
  SUM(x.tmp) as tmp
FROM
  (
      SELECT
          w.weight, s.name, SUM(g.grade*w.weight)/COUNT(*))/100 AS tmp
      FROM
          grades g
              JOIN subjects s ON s.recno = g.subject
              JOIN weights ON w.recno = g.weight
      GROUP BY
          w.weight, s.name
) x
GROUP BY
  x.Feld;

Und immer noch wird die Exception "Operation wird nicht unterstüzt" ausgelöst. Aber dann glaube ich ihm halt mal, dass die Operation nicht unterstüzt wird... SQLite ist eben
Zitat:

Zitat von Furtbichler (Beitrag 1252251)
wirklich 'SQL light' [zumindest unter iOS]

Ohne Subselect funktionierts.
Das ist jetzt aber nicht weiter schlimm, muss halt alles weitere in Delphi ausführen, kosten auch nicht soo viel mehr Zeit.

Und danke Furtbichler, dass du mein Beispiel verbessert hast. Damit hast du ein weites Problem gelöst ;)

jobo 17. Mär 2014 16:17

AW: SQLite - Select mit mehreren Tabellen
 
Zitat:

Zitat von Crocotronic (Beitrag 1252264)
SQL-Code:
SELECT
  1 as Feld,
  SUM(x.tmp) as tmp
FROM
  (
      SELECT
          w.weight, s.name, SUM(g.grade*w.weight)/COUNT(*))/100 AS tmp
      FROM
          grades g
              JOIN subjects s ON s.recno = g.subject
              JOIN weights ON w.recno = g.weight
      GROUP BY
          w.weight, s.name
) x
GROUP BY
  x.Feld;
Und immer noch wird die Exception "Operation wird nicht unterstüzt" ausgelöst. Aber dann glaube ich ihm halt mal, dass die Operation nicht unterstüzt wird... SQLite ist eben
Zitat:

Zitat von Furtbichler (Beitrag 1252251)
wirklich 'SQL light' [zumindest unter iOS]

Ohne Subselect funktionierts.
Das ist jetzt aber nicht weiter schlimm, muss halt alles weitere in Delphi ausführen, kosten auch nicht soo viel mehr Zeit.

Das Group By wird so auch nicht unbedingt unterstüzt. Ich weiß nicht, ob das in jedem System so ist, aber der vergebene Alias "Feld" ist dem Group by nicht unbedingt bekannt, da er nicht aus der FROM Quelle kommt, sondern erst danach im Select Statement erzeugt wird.
An dieser Stelle kann man im Group By statt der Feldnamen höchstens mit den Feldnummern des Select Statements arbeiten. Hier zufällig die "1" als Konstante, entsprechend Feldnummer 1.

Das ist zumindest nich nur bei "light" Systemen so.

Group by sähe also eher so aus:
Code:
group by 1;


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:50 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz