Access-o-Mania

Access-Forum (Deutsch/German) => Tabelle/Abfrage => Thema gestartet von: ElkeS am Juli 15, 2015, 10:04:10

Titel: Unterabfragen
Beitrag von: ElkeS am Juli 15, 2015, 10:04:10
Hallo,
hab ein Problem mit Abfragen:
ich möchte außer der Abfrage nach den letzten eingegebenen Werten auch die Anzahl der schon eingegebenen Werte haben.
Also letzter Wert über folgenden Befehl:

SELECT *
FROM tblWeight2015
WHERE (tblWeight2015.bytWeightID)=(
SELECT Top 1 temp.bytWeightID
FROM tblWeight2015 as temp
WHERE temp.bytMasterID=tblWeight2015.bytMasterID
ORDER by temp.datWeight desc
);

...funktioniert perfekt! Nun aber noch die Anzahl der Gewichtsmessungen? Geht das nur über eine Extraabfrage oder lässt sich das auch mit einer Unter-(Unter)- abfrage erledigen?
Nächste Frage:
Ich habe eine Abfrage – sie basiert auf 4 Tabellen und 6 Abfragen (eben solchen, wie oben beschrieben) und daraus wird eine Bericht (Etikett) generiert zum Ausdrucken. Nun dauert mir die Berichtsgenerierung zu lange. Kann man da etwas optimieren? – oder müssen die Abfragen anders gestellt werden.
Gruß ElkeS
Titel: Re: Unterabfragen
Beitrag von: MaggieMay am Juli 15, 2015, 17:20:36
Hi,

kann es sein, dass du folgendes meinst:
SELECT *, (Select Count(*) From tblWeight2015 As h Where h.bytMasterID=tblWeight2015.bytMasterID) As anz
FROM tblWeight2015
WHERE (tblWeight2015.bytWeightID)=(
SELECT Top 1 temp.bytWeightID
FROM tblWeight2015 as temp
WHERE temp.bytMasterID=tblWeight2015.bytMasterID
ORDER by temp.datWeight desc
);
Titel: Re: Unterabfragen
Beitrag von: ElkeS am Juli 16, 2015, 08:06:16
...meinte ich – genauso soll es sein! Vielen, vielen Dank – das bringt mich wieder ein ganzes Stück weiter...jetzt habe ich auch die Syntax verstanden! Im Prinzip sind es jetzt 2 Unterabfragen – eine zum Heraussuchen des maximalen Datums und eine zum Zählen – zusammen in einer Abfrage. Ich hatte versucht in der Unterabfrage nach dem MaxDatum – die Zählabfrage unterzubringen –
Nun werde ich meine Abfragen anpassen und sehen, ob sich mit der Zeit zur Berichtserstellung auch etwas tut...
Nochmals vielen Dank!
ElkeS
Titel: Re: Unterabfragen
Beitrag von: ElkeS am Juli 16, 2015, 14:34:53
Hallo,
SELECT *, (
Select Count(*) From tblIndivTests2015 As h Where h.bytMasterID=tblIndivTests2015.bytMasterID) As anz
FROM tblIndivTests2015
WHERE (tblIndivTests2015.bytIndivTestsID)=(
SELECT Top 1 temp.bytIndivTestsID
FROM tblIndivTests2015 as temp
WHERE temp.bytMasterID=tblIndivTests2015.bytMasterID
ORDER by temp.datStart desc
);

Fehlermeldung:

Höchstens ein Datensatz kann von dieser Unterabfrage zurückgegeben werden.

...was passiert da? Warum klappt das bei einer Tabelle und bei der nächsten Tabelle nicht?
Bin etwas ratlos? Habe die Tabellen überprüft, habe den Code kontrolliert...
Gruß ElkeS
Titel: Re: Unterabfragen
Beitrag von: DF6GL am Juli 16, 2015, 14:59:34
Hallo,

ich denke mal, die ganze SQL-Konstruktion liesse sich über eine Gruppierende Abfrage ohne Unterabfragen eleganter lösen...aber ich kenne jetzt nicht die genauen Vorgaben...


Versuch mal so:


SELECT *,
(
    Select Count(*) From tblIndivTests2015 As h Where h.bytMasterID=tblIndivTests2015.bytMasterID
)   As anz
FROM tblIndivTests2015 WHERE tblIndivTests2015.bytIndivTestsID IN
     (
       SELECT Top 1 temp.bytIndivTestsID FROM tblIndivTests2015 as temp WHERE
temp.bytMasterID=tblIndivTests2015.bytMasterID
ORDER by temp.datStart desc
     )

Titel: Re: Unterabfragen
Beitrag von: ElkeS am Juli 16, 2015, 15:38:51
Hallo,

danke! Jetzt scheint (?) es zu funktionieren. Eine elegantere Lösung mit Gruppierung ohne Unterabfrage? Ich brauche aber auch den ganzen Satz zum letzten Datum (also alle Werte zum letzten Datum)?

Gruß ElkeS
Titel: Re: Unterabfragen
Beitrag von: ebs17 am Juli 17, 2015, 08:18:28
Wenn ich das richtig verstanden habe:
SELECT
   T.*,
   U.AE
FROM
   (
      SELECT
         bytWeightID,
         bytMasterID,
         MAX(datWeight) AS MaxDate,
         COUNT(*) AS AE
      FROM
         tblWeight2015
      GROUP BY
         bytWeightID,
         bytMasterID
   ) AS U
      INNER JOIN tblWeight2015 AS T
      ON U.bytWeightID = T.bytWeightID
         AND
      U.bytMasterID = T.bytMasterID
         AND
      U.MaxDate = T.datWeight


ZitatNächste Frage:
Ich habe eine Abfrage – sie basiert auf 4 Tabellen und 6 Abfragen (eben solchen, wie oben beschrieben) und daraus wird eine Bericht (Etikett) generiert zum Ausdrucken. Nun dauert mir die Berichtsgenerierung zu lange. Kann man da etwas optimieren? – oder müssen die Abfragen anders gestellt werden.
Ja und Ja.
Titel: Re: Unterabfragen
Beitrag von: ElkeS am Juli 17, 2015, 12:02:07
Hallo zurück,
habe es angepaßt:

SELECT  T.bytMasterID, T.datWeight, T.dblWeight, U.AE
FROM (
SELECT bytMasterID, MAX(datWeight) AS MaxDate, COUNT(*) AS AE
FROM tblWeight2015
GROUP BY bytMasterID
) AS U
INNER JOIN tblWeight2015 AS T
ON U.bytMasterID = T.bytMasterID AND U.MaxDate = T.datWeight

läuft gut und ist wesentlich schneller als die andere Variante! Ich werde meine anderen Abfragen auch verändern und sehen ob mir das als Optimierung schon reicht oder gibt es noch etwas Besseres? "Ja und Ja" ?
Gruß ElkeS

Titel: Re: Unterabfragen
Beitrag von: ebs17 am Juli 17, 2015, 13:06:40
Zitatoder gibt es noch etwas Besseres?

Das kommt darauf an:
- Datenmengen,
- vorhandene Tabellenstrukturen,
- das Abfrageziel,
- Indizierung (Entwickleraufgabe).

Daraus kann man dann Abfragedesign ableiten, gerne auch in Varianten, um vergleichen zu können.

Zitatwesentlich schneller als die andere Variante
Die Unterabfrage im FROM-Teil wird nur einmal ausgeführt, während Unterabfragen im WHERE-Teil und ganz besonders im SELECT-Teil mehrfach (bis einmal pro Datensatz der Hauptabfrage) ausgeführt werden.
Siehe dazu auch Grundlagen - SQL ist leicht ( 8 ) - Index (http://www.ms-office-forum.net/forum/showthread.php?t=317707).