Hi nette Profis, kann ich diese Abfrage Optimieren

Technic1965

Mitglied
Kann ich diese Abfrage optimieren? ein Beispiel würde mir vielleicht weiterhelfen :(

SQL:
(Sum((SELECT
IfNull(Sum(davidw2000._mtbl_leistsonstiges.lsdauer), 0)
FROM
davidw2000._mtbl_leistsonstiges
WHERE
davidw2000._mtbl_leist.id_flleist = davidw2000._mtbl_leistsonstiges.id_flleist AND
davidw2000._mtbl_leistsonstiges.id_lsart IN (38)))) AS Urlaub,
(Sum((SELECT
IfNull(Sum(davidw2000._mtbl_leistsonstiges.lsdauer), 0)
FROM
davidw2000._mtbl_leistsonstiges
WHERE
davidw2000._mtbl_leist.id_flleist = davidw2000._mtbl_leistsonstiges.id_flleist AND
davidw2000._mtbl_leistsonstiges.id_lsart IN (40)))) AS Krank,
(Sum((SELECT
IfNull(Sum(davidw2000._mtbl_leistsonstiges.lsdauer), 0)
FROM
davidw2000._mtbl_leistsonstiges
WHERE
davidw2000._mtbl_leist.id_flleist = davidw2000._mtbl_leistsonstiges.id_flleist AND
davidw2000._mtbl_leistsonstiges.id_lsart IN (42)))) AS Feiertag
 
Moin Technic1965,

es geht doch immer noch um diese Abfrage aus deinem letzten Beitrag, den du als gelöst markiert hast?

Sprich, der Ausschnitt, den du gepostet hast, ist Teil einer Abfrage, die wie folgt aufgebaut ist
SQL:
SELECT 
  -- <Klartextfelder für Mitarbeiter + Tage laut Tabelle "Leistung">
    <dein Ausschnitt oben>
FROM <4 verknibbelte Tabellen>
WHERE <mitarbeiternr= x und Zeitraum between y und z>
GROUP BY <mitarbeiternr und gefundene Tage>

Da die Tabellen, aus denen du jetzt die Urlaub/Krank/Feiertage holst, ohnehin schon in der Zeile
FROM <4 verknibbelte Tabellen>
... vorhanden sind, brauchst du wirklich nicht diese Werte mit einem Inline.Select zu holen.

Das obige Geraffel würde im ersten Ansatz so aussehen:
SQL:
Select
      leist.id_nrmitar
    , leist.lsdate
    , case when (Sum (case when lsonst.id_lsart = 38
                           then lsonst.lsdauer
                           else 0 end   ) > 0
           then 'U' else '-' end as Urlaub
    , case when (Sum (case when lsonst.id_lsart = 40
                           then lsonst.lsdauer
                           else 0 end ) > 0
           then 'K' else '-' end as Krank
    , case when(Sum (case when lsonst.id_lsart = 42
                          then lsonst.lsdauer
                          else 0 end ) > 0
           then 'F' else '-' end as Feiertag
FROM davidw2000._mtbl_leist as leist
   LEFT JOIN davidw2000._mtbl_leistsonstiges as lsonst on leist.id_flleist = lsonst.id_flleist
   -- weitere JOINs ...
   -- WHERE ... <mitarbeiter=x und Zeitraum between y and z>
GROUP BY
  leist.id_nrmitar,
  leist.lsdate
;
;

Ist auch nicht gerade wartungsfreundlich durch die notwendigen verschachtelten CASE WHENs.

Geschickter wäre es eher, die Klamotte aufzuteilen in ein inneres SELECT, in dem die Summenwerte aus allen Tabellen geholt werden, die irgendwie an der Haupttabelle "Leistungen" (=davidw2000._mtbl_leist) hängen UND datumsabhängige Zahlenwerte enthalten. Also alles, was tatsächlich mit GROUP BY zusammengedampf werden soll, NICHT aber diese Dimensionstabellen für Anrede und Mitarbeiterdaten im Klartext (Name, Vorname, Sternzeichen,,) .
Die brauchen nicht gruppiert werden und können später an das Summen-Resultset drangeflanscht werden.

Eine grobe Skizze für die Gesamtabfrage war demzufolge das hier:
SQL:
SELECT anr.Text           AS Anrede
     , stamm.mavname     AS Vorname,
     , stammdaten.maname AS Name,
     -- , x.id_nrmitar /* interne ID, muss nicht angezeigt werden */
     , x.lsdate
     , case when x.sumUrlaub   > 0 then 'U' else '-' end as Urlaub
     , case when x.sumKrank    > 0 then 'K' else '-' end as Krank
     , case when x.SumFeiertag > 0 then 'F' else '-' end as Feiertag
FROM (
    /* inneres SELECT: alle Summenwerte aus einem SELECT von Tabelle "leist" mit allen ihren Childs */
     Select  leist.id_nrmitar
           , leist.lsdate
           , Sum (case when lsonst.id_lsart = 38
                       then lsonst.lsdauer
                      else 0 end   ) as sumUrlaub 
            , Sum (case when lsonst.id_lsart = 40
                        then lsonst.lsdauer
                        else 0 end ) as SumKrank
            , Sum (case when lsonst.id_lsart = 42
                       then lsonst.lsdauer
                       else 0 end ) as SumFeiertag
        FROM davidw2000._mtbl_leist as leist
          -- weitere JOINs .. (hier nicht wesentlich)
           -- LEFT JOIN davidw2000._kde_leist...
           -- LEFT JOIN davidw2000._mtbl_leistunterricht
           LEFT JOIN davidw2000._mtbl_leistsonstiges as lsonst
              on leist.id_flleist = lsonst.id_flleist
        WHERE leist.id_nrmitar = 5
          AND leist.lsdate BETWEEN '2017-06-01 00:00:00' AND '2017-06-31 23:59:59'
        GROUP BY
          leist.id_nrmitar,
          leist.lsdate
        )  as x

  INNER JOIN davidw2000._mtbl_stammdaten AS Stamm ON x.id_nrmitar = Stamm.id_mitar
  INNER JOIN davidw2000._sys_anrede      AS Anr   ON Stamm.id_anrnr = anr.id_anrnr

Ist natürlich von mir nur biooptisch auf Tippfehler geprüft worden, testen kann ich es nicht.
Kannst ja mal die letzte Codevariante antesten - die sollte zeigen, ob es prinzipiell works as designed.

Grüße
Biber
 
Moin Technic1965,

es geht doch immer noch um diese Abfrage aus deinem letzten Beitrag, den du als gelöst markiert hast?

Sprich, der Ausschnitt, den du gepostet hast, ist Teil einer Abfrage, die wie folgt aufgebaut ist
SQL:
SELECT
  -- <Klartextfelder für Mitarbeiter + Tage laut Tabelle "Leistung">
    <dein Ausschnitt oben>
FROM <4 verknibbelte Tabellen>
WHERE <mitarbeiternr= x und Zeitraum between y und z>
GROUP BY <mitarbeiternr und gefundene Tage>

Da die Tabellen, aus denen du jetzt die Urlaub/Krank/Feiertage holst, ohnehin schon in der Zeile
FROM <4 verknibbelte Tabellen>
... vorhanden sind, brauchst du wirklich nicht diese Werte mit einem Inline.Select zu holen.

Das obige Geraffel würde im ersten Ansatz so aussehen:
SQL:
Select
      leist.id_nrmitar
    , leist.lsdate
    , case when (Sum (case when lsonst.id_lsart = 38
                           then lsonst.lsdauer
                           else 0 end   ) > 0
           then 'U' else '-' end as Urlaub
    , case when (Sum (case when lsonst.id_lsart = 40
                           then lsonst.lsdauer
                           else 0 end ) > 0
           then 'K' else '-' end as Krank
    , case when(Sum (case when lsonst.id_lsart = 42
                          then lsonst.lsdauer
                          else 0 end ) > 0
           then 'F' else '-' end as Feiertag
FROM davidw2000._mtbl_leist as leist
   LEFT JOIN davidw2000._mtbl_leistsonstiges as lsonst on leist.id_flleist = lsonst.id_flleist
   -- weitere JOINs ...
   -- WHERE ... <mitarbeiter=x und Zeitraum between y and z>
GROUP BY
  leist.id_nrmitar,
  leist.lsdate
;
;

Ist auch nicht gerade wartungsfreundlich durch die notwendigen verschachtelten CASE WHENs.

Geschickter wäre es eher, die Klamotte aufzuteilen in ein inneres SELECT, in dem die Summenwerte aus allen Tabellen geholt werden, die irgendwie an der Haupttabelle "Leistungen" (=davidw2000._mtbl_leist) hängen UND datumsabhängige Zahlenwerte enthalten. Also alles, was tatsächlich mit GROUP BY zusammengedampf werden soll, NICHT aber diese Dimensionstabellen für Anrede und Mitarbeiterdaten im Klartext (Name, Vorname, Sternzeichen,,) .
Die brauchen nicht gruppiert werden und können später an das Summen-Resultset drangeflanscht werden.

Eine grobe Skizze für die Gesamtabfrage war demzufolge das hier:
SQL:
SELECT anr.Text           AS Anrede
     , stamm.mavname     AS Vorname,
     , stammdaten.maname AS Name,
     -- , x.id_nrmitar /* interne ID, muss nicht angezeigt werden */
     , x.lsdate
     , case when x.sumUrlaub   > 0 then 'U' else '-' end as Urlaub
     , case when x.sumKrank    > 0 then 'K' else '-' end as Krank
     , case when x.SumFeiertag > 0 then 'F' else '-' end as Feiertag
FROM (
    /* inneres SELECT: alle Summenwerte aus einem SELECT von Tabelle "leist" mit allen ihren Childs */
     Select  leist.id_nrmitar
           , leist.lsdate
           , Sum (case when lsonst.id_lsart = 38
                       then lsonst.lsdauer
                      else 0 end   ) as sumUrlaub
            , Sum (case when lsonst.id_lsart = 40
                        then lsonst.lsdauer
                        else 0 end ) as SumKrank
            , Sum (case when lsonst.id_lsart = 42
                       then lsonst.lsdauer
                       else 0 end ) as SumFeiertag
        FROM davidw2000._mtbl_leist as leist
          -- weitere JOINs .. (hier nicht wesentlich)
           -- LEFT JOIN davidw2000._kde_leist...
           -- LEFT JOIN davidw2000._mtbl_leistunterricht
           LEFT JOIN davidw2000._mtbl_leistsonstiges as lsonst
              on leist.id_flleist = lsonst.id_flleist
        WHERE leist.id_nrmitar = 5
          AND leist.lsdate BETWEEN '2017-06-01 00:00:00' AND '2017-06-31 23:59:59'
        GROUP BY
          leist.id_nrmitar,
          leist.lsdate
        )  as x

  INNER JOIN davidw2000._mtbl_stammdaten AS Stamm ON x.id_nrmitar = Stamm.id_mitar
  INNER JOIN davidw2000._sys_anrede      AS Anr   ON Stamm.id_anrnr = anr.id_anrnr

Ist natürlich von mir nur biooptisch auf Tippfehler geprüft worden, testen kann ich es nicht.
Kannst ja mal die letzte Codevariante antesten - die sollte zeigen, ob es prinzipiell works as designed.

Grüße
Biber

Danke Biber3,

hatte erst Zeit gehabt, verstehe gerade nicht was dieser Fehler bedeutet:
SQL Fehler (1630): FUNKTION davidw2000.SUM does not exist. Check the 'Funktion Name Parsing and Resolution' section in the Reference Manual
 
Zuletzt bearbeitet von einem Moderator:
Moin Technic1965,

sorry, mein Fehler.
Es darf natürlich bei der SUM()-Function kein Leerzeichen zwischen "SUM" und der öffnenden Klammer sein.

Ersetze bitte jeweils das "SUM (CASE WHEN ..." durch "SUM(CASE WHEN..."

Andere Tippfehler habe ich auch noch in Zeile 2 und 3 des letzten Statements gesehen.
Hier statt " , stammdaten.maname AS Name" den richtigen Alias " , stamm.maname AS Name"
und jeweils das Komma am Ende der Zeile entfernen.

SQL:
SELECT anr.Text           AS Anrede
     , stamm.mavname     AS Vorname
     , stamm.maname AS Name
     , <bla>....


Grüße
Biber
 
HI Biber3

mittlerweile sieht es so aus
SQL:
SELECT Anr.Text AS Anrede,
stamm.mavname AS Vorname,
stamm.maname AS Name,
Date_Format(x.lsdate, '%d.%m.%Y') AS Datum,
Ifnull(x.sumTheorie ,0) AS Theorie,
CASE WHEN x.sumFahrs_Mofa > 0 THEN Ifnull(x.sumFahrs_Mofa ,0) ELSE '-' END AS Fahrs_Mofa,
CASE WHEN x.sumFahrs_AM > 0 THEN Ifnull(x.sumFahrs_AM ,0) ELSE '-' END AS Fahrs_AM,
CASE WHEN x.sumFahrs_A1 > 0 THEN Ifnull(x.sumFahrs_A1 ,0) ELSE '-' END AS Fahrs_A1,
CASE WHEN x.sumFahrs_AA2 > 0 THEN Ifnull(x.sumFahrs_AA2 ,0) ELSE '-' END AS Fahrs_AA2,
CASE WHEN x.sumFahrs_B > 0 THEN Ifnull(x.sumFahrs_B ,0) ELSE '-' END AS Fahrs_B,
CASE WHEN x.sumFahrs_BE > 0 THEN Ifnull(x.sumFahrs_BE ,0) ELSE '-' END AS Fahrs_BE,

CASE WHEN x.sumUrlaub > 0 THEN 'U' ELSE '-' END AS Urlaub,
CASE WHEN x.sumKrank > 0 THEN 'K' ELSE '-' END AS Krank,
CASE WHEN x.SumFeiertag > 0 THEN 'F' ELSE '-' END AS Feiertag

FROM (

[I]/* inneres SELECT: alle Summenwerte aus einem SELECT von Tabelle "leist" mit allen ihren Childs */
[/I]
SELECT leist.id_nrmitar, leist.lsdate,
SUM(ltheo.dauer) AS sumTheorie,

SUM(CASE WHEN lfahrs.isUnterschrift = True
AND lfahrs.is_fsklnr IN ('27')

THEN lfahrs.lsdauer
ELSE 0 END ) AS sumFahrs_Mofa,

SUM(CASE WHEN lfahrs.isUnterschrift = True
AND lfahrs.is_fsklnr IN ('50')

THEN lfahrs.lsdauer
ELSE 0 END ) AS sumFahrs_AM,

SUM(CASE WHEN lfahrs.isUnterschrift = True
AND lfahrs.is_fsklnr IN ('13')

THEN lfahrs.lsdauer
ELSE 0 END ) AS sumFahrs_A1,

SUM(CASE WHEN lfahrs.isUnterschrift = True
AND lfahrs.is_fsklnr IN ('51','53')

THEN lfahrs.lsdauer
ELSE 0 END ) AS sumFahrs_AA2,

SUM(CASE WHEN lfahrs.isUnterschrift = True
AND lfahrs.is_fsklnr IN ('15')

THEN lfahrs.lsdauer
ELSE 0 END ) AS sumFahrs_B,

SUM(CASE WHEN lfahrs.isUnterschrift = True
AND lfahrs.is_fsklnr IN ('52')

THEN lfahrs.lsdauer
ELSE 0 END ) AS sumFahrs_BE,

SUM(CASE WHEN lsonst.id_lsart = 38
THEN lsonst.lsdauer
ELSE 0 END ) AS sumUrlaub,

SUM(CASE WHEN lsonst.id_lsart = 40
THEN lsonst.lsdauer
ELSE 0 END ) AS SumKrank,

SUM(CASE WHEN lsonst.id_lsart = 42
THEN lsonst.lsdauer
ELSE 0 END ) AS SumFeiertag
FROM davidw2000._mtbl_leist AS leist

LEFT JOIN davidw2000._mtbl_leistsonstiges AS lsonst ON leist.id_flleist = lsonst.id_flleist
LEFT JOIN davidw2000._mtbl_leistunterricht AS ltheo ON leist.id_flleist = ltheo.id_flleist
LEFT JOIN davidw2000._kde_leist AS lkde ON leist.id_flleist = lkde.id_flleist
LEFT JOIN davidw2000._kde_leistfahrstunden AS lfahrs ON lkde.id_kdleist = lfahrs.id_kdleist
LEFT JOIN davidw2000._kde_leistpruefungpraxis AS lprapru ON lkde.id_kdleist = lprapru.id_kdleist

WHERE leist.id_nrmitar = 3
AND leist.lsdate BETWEEN '2017-06-01 00:00:00' AND '2017-06-31 23:59:59'
GROUP BY


leist.id_nrmitar,
leist.lsdate DESC) AS x

INNER JOIN davidw2000._mtbl_stammdaten AS Stamm ON x.id_nrmitar = Stamm.id_mitar
INNER JOIN davidw2000._sys_anrede AS Anr ON Stamm.id_anrnr = Anr.id_anrnr

Dauer von 1 Abfrage: 0,969 sec.
ich ändere mal das ganze und melde mich nochmal in 1-2 Tagen, was mich gerade ärgert ist das wenn ich die Tabelle
SQL:
LEFT JOIN davidw2000._kde_leist AS lkde ON leist.id_flleist = lkde.id_flleist
verbinde, bekomme ich hier
SQL:
Ifnull(x.sumTheorie ,0) AS Theorie
eine Menge von Unt. Minuten also holt sich noch von der Tabelle (davidw2000._kde_leist) Daten.
 
Moin Technic1965,

ein paar Rückfragen und Anmerkungen hätte ich noch, die dann in den nächsten 1, 2 Tagen mit in deinen nächsten Kommentar einarbeiten könntest.

Rückfragen:
- kommt denn inhaltlich ein plausibles Ergebnis heraus, welches sich mit den Ergebnissen der Ur-Abfrage (also dem Stand von August) deckt?
- was bedeutet "Dauer von 1 Abfrage: 0,969 sec"? Ist das akzeptabel oder sollten wir ein bisschen optimieren? Wie lange hatte den die Ur-Abfrage gebraucht?
- den Satz ganz unten "...eine Menge von Unt. Minuten also holt sich noch von der Tabelle (davidw2000._kde_leist) Daten." hab ich nicht verstanden. Kannst du den mal mit anderen Worten ausdrücken?

letzte Rückfrage: was ist denn aus dem "geteilt durch 45" geworden, welches doch bei vielen Summen verwendet wurde, um von Minuten auf Unterrichtsstunden zu kommen?

Anmerkungen:
- in diesen Konstrukten
SQL:
 CASE WHEN x.sumFahrs_A1 > 0 THEN Ifnull(x.sumFahrs_A1 ,0) ELSE '-' END AS Fahrs_A1,
...ist die Ifnull()-Prüfung Dönekens. WENN summebla größer 0 ist, kann sie nicht NULL sein. Streiche IsNull()

Bei den folgenden Konstrukten:
SQL:
SUM(CASE WHEN lfahrs.isUnterschrift = TRUE
AND lfahrs.is_fsklnr IN ('52')
-> da IMMER nur Datensätze mit "lfahrs.isUnterschrift = TRUE" berücksichtigt werden, kann diese Bedingung einfach zusätzlich mit in den LEFT JOIN, mit dem die lfahrs-Tabelle drangeflanscht wird. Dann brauchst du es nicht in jedem CASE-Fall.
Außerdem könnte , wenn nur ein Wert geprüft muss , statt "lfahrs.is_fsklnr IN ('52')" ein "lfahrs.is_fsklnr ='52'" performanter sein.
Und sind diese fsklnr wirklich vom Typ String, also '52', '15' usw. oder doch vielleicht Zahlen 52, 15, etc?
Falls es in der Tabelle Zahlen sind, dann solltest du es auch in der Query ohne Anführungszeichen schreiben, da dein mySQL sonst immer eine (unnötige) implizite Typkonvertierung machen muss.

Ganz unten in deiner Query steht

GROUP BY
leist.id_nrmitar,
leist.lsdate DESC) AS x

WTF soll denn das Schlüsselwort "DESC"da ? Das gehört ggf. in eine zusätzliche ORDER BY-Klausel als allerletzte Zeile, wenn du den Resultset sortiert haben willst.
Kannst also als neue letzte Zeile ergänzen
" ORDER BY x.lsdate DESC" (ist ja nur ein Mitarbeiter, also brauchst du nicht mher nach Mitarbeiter sortieren)
Und das "DESC" beim GROUP BY" ersatzlos streichen, sonst bringst du deine Datenbank unnötig in Grübeleien.

Grüße
Biber
 
Zuletzt bearbeitet:
Danke dir Biber3,
Werde ich tun, auf jedenfall und mit klarem Kopf nochmal kommentieren, ich war wohl wieder zu müde, nochmals danke.

So Bieber3 mitlerweile sieht es so aus, habe aber "x.sumTheorie As Theorie" ein problem wenn _mtbl_leist.id_flleist mit der _kde_leist.id_flleist verbinde bekommt man mehr Arbeitszeiten weil in der kde_leist Tabelle einträge der kunden sind die in einem 90 min unterricht waren, wenn im unterricht 5 kunden waren dann bekommt man 5x90 also 450 min statt 90 min, lösche ich "LEFT JOIN davidw2000._kde_leist AS lkde ON leist.id_flleist = lkde.id_flleist" dan bekomme ich 90 min also nur die in der _mtbl_leist Tabelle, wie kann ich vermeiden das durch die Verbindung auch Arbeitszeiten aus _kde_leist geholt werden
upload_2017-8-9_22-30-43.pngupload_2017-8-9_22-29-13.png upload_2017-8-9_22-30-43.png
SQL:
SELECT Anr.Text AS Anrede,
stamm.mavname AS Vorname,
stamm.maname AS Name,
Date_Format(x.lsdate, '%d.%m.%Y') AS Datum,
x.sumTheorie AS Theorie,
CASE WHEN x.sumFahrs_Mofa > 0 THEN x.sumFahrs_Mofa ELSE '-' END AS Fahrs_Mofa,
CASE WHEN x.sumFahrs_AM > 0 THEN x.sumFahrs_AM ELSE '-' END AS Fahrs_AM,
CASE WHEN x.sumFahrs_A1 > 0 THEN x.sumFahrs_A1 ELSE '-' END AS Fahrs_A1,
CASE WHEN x.sumFahrs_A > 0 THEN x.sumFahrs_A ELSE '-' END AS Fahrs_A,
CASE WHEN x.sumFahrs_A2 > 0 THEN x.sumFahrs_A2 ELSE '-' END AS Fahrs_A2,
CASE WHEN x.sumFahrs_B > 0 THEN x.sumFahrs_B ELSE '-' END AS Fahrs_B,
CASE WHEN x.sumFahrs_BE > 0 THEN x.sumFahrs_BE ELSE '-' END AS Fahrs_BE,
CASE WHEN x.sumPraPru_AM > 0 THEN x.sumPraPru_AM ELSE '-' END AS Prax_AM,
CASE WHEN x.sumPraPru_A1 > 0 THEN x.sumPraPru_A1 ELSE '-' END AS Prax_A1,
CASE WHEN x.sumPraPru_A > 0 THEN x.sumPraPru_A ELSE '-' END AS Prax_A,
CASE WHEN x.sumPraPru_A2 > 0 THEN x.sumPraPru_A2 ELSE '-' END AS Prax_A2,
CASE WHEN x.sumPraPru_B > 0 THEN x.sumPraPru_B ELSE '-' END AS Prax_B,
CASE WHEN x.sumPraPru_BE > 0 THEN x.sumPraPru_BE ELSE '-' END AS Prax_BE,
CASE WHEN x.sumUrlaub > 0 THEN 'U' ELSE '-' END AS Urlaub,
CASE WHEN x.sumKrank > 0 THEN 'K' ELSE '-' END AS Krank,
CASE WHEN x.SumFeiertag > 0 THEN 'F' ELSE '-' END AS Feiertag

FROM (

SELECT leist.id_nrmitar,
leist.lsdate,
SUM(ltheo.dauer) AS sumTheorie,

SUM(CASE WHEN lfahrs.is_fsklnr = 27
THEN lfahrs.lsdauer
ELSE 0 END ) AS sumFahrs_Mofa,

SUM(CASE WHEN lfahrs.is_fsklnr = 50
THEN lfahrs.lsdauer
ELSE 0 END ) AS sumFahrs_AM,

SUM(CASE WHEN lfahrs.is_fsklnr = 13
THEN lfahrs.lsdauer
ELSE 0 END ) AS sumFahrs_A1,

SUM(CASE WHEN lfahrs.is_fsklnr = 51
THEN lfahrs.lsdauer
ELSE 0 END ) AS sumFahrs_A,

SUM(CASE WHEN lfahrs.is_fsklnr = 53
THEN lfahrs.lsdauer
ELSE 0 END ) AS sumFahrs_A2,

SUM(CASE WHEN lfahrs.is_fsklnr = 15
THEN lfahrs.lsdauer
ELSE 0 END ) AS sumFahrs_B,

SUM(CASE WHEN lfahrs.is_fsklnr = 52
THEN lfahrs.lsdauer
ELSE 0 END ) AS sumFahrs_BE,

SUM(CASE WHEN lprapru.id_fsklnr = 50
THEN lprapru.lsdauer
ELSE 0 END ) AS sumPraPru_AM,

SUM(CASE WHEN lprapru.id_fsklnr = 13
THEN lprapru.lsdauer
ELSE 0 END ) AS sumPraPru_A1,

SUM(CASE WHEN lprapru.id_fsklnr = 51
THEN lprapru.lsdauer
ELSE 0 END ) AS sumPraPru_A,

SUM(CASE WHEN lprapru.id_fsklnr = 53
THEN lprapru.lsdauer
ELSE 0 END ) AS sumPraPru_A2,

SUM(CASE WHEN lprapru.id_fsklnr = 15
THEN lprapru.lsdauer
ELSE 0 END ) AS sumPraPru_B,

SUM(CASE WHEN lprapru.id_fsklnr = 52
THEN lprapru.lsdauer
ELSE 0 END ) AS sumPraPru_BE,

SUM(CASE WHEN lsonst.id_lsart = 38
THEN lsonst.lsdauer
ELSE 0 END ) AS sumUrlaub,
SUM(CASE WHEN lsonst.id_lsart = 40
THEN lsonst.lsdauer
ELSE 0 END ) AS SumKrank,

SUM(CASE WHEN lsonst.id_lsart = 42
THEN lsonst.lsdauer
ELSE 0 END ) AS SumFeiertag

FROM davidw2000._mtbl_leist AS leist

LEFT JOIN davidw2000._mtbl_leistsonstiges AS lsonst ON leist.id_flleist = lsonst.id_flleist
LEFT JOIN davidw2000._mtbl_leistunterricht AS ltheo ON leist.id_flleist = ltheo.id_flleist
LEFT JOIN davidw2000._kde_leist AS lkde ON leist.id_flleist = lkde.id_flleist
LEFT JOIN davidw2000._kde_leistfahrstunden AS lfahrs ON lkde.id_kdleist = lfahrs.id_kdleist AND lfahrs.isUnterschrift = True
LEFT JOIN davidw2000._kde_leistpruefungpraxis AS lprapru ON lkde.id_kdleist = lprapru.id_kdleist AND lprapru.isUnterschrift = True

WHERE leist.id_nrmitar = 1
AND leist.lsdate BETWEEN '2017-06-01 00:00:00' AND '2017-06-30 23:59:59'
GROUP BY
leist.id_nrmitar,
leist.lsdate
ORDER BY leist.lsdate DESC) AS x

INNER JOIN davidw2000._mtbl_stammdaten AS Stamm ON x.id_nrmitar = Stamm.id_mitar
INNER JOIN davidw2000._sys_anrede AS Anr ON Stamm.id_anrnr = Anr.id_anrnr[sql]

Also so hätte ich richtige Ergebnissen wenn ich aber Tabelle "_mtbl_leist" nicht mit "_kde_leist" verbinde bekomme ich die Werte aus der Tabelle "_kde_leistfahrstunden" und  "_kde_leistpruefungpraxis"  nicht, wie unten sind die Theoriezeiten richtig
[ATTACH=full]65214[/ATTACH]

[code=SQL]
SELECT Anr.Text AS Anrede,
stamm.mavname AS Vorname,
stamm.maname AS Name,
Date_Format(x.lsdate, '%d.%m.%Y') AS Datum,
x.sumTheorie AS Theorie,

CASE WHEN x.sumUrlaub > 0 THEN 'U' ELSE '-' END AS Urlaub,
CASE WHEN x.sumKrank > 0 THEN 'K' ELSE '-' END AS Krank,
CASE WHEN x.SumFeiertag > 0 THEN 'F' ELSE '-' END AS Feiertag

FROM (
SELECT leist.id_nrmitar,
leist.lsdate,

SUM(ltheo.dauer) AS sumTheorie,

SUM(CASE WHEN lsonst.id_lsart = 38
THEN lsonst.lsdauer
ELSE 0 END ) AS sumUrlaub,

SUM(CASE WHEN lsonst.id_lsart = 40
THEN lsonst.lsdauer
ELSE 0 END ) AS SumKrank,

SUM(CASE WHEN lsonst.id_lsart = 42
THEN lsonst.lsdauer
ELSE 0 END ) AS SumFeiertag
FROM davidw2000._mtbl_leist AS leist
LEFT JOIN davidw2000._mtbl_leistsonstiges AS lsonst ON leist.id_flleist = lsonst.id_flleist
LEFT JOIN davidw2000._mtbl_leistunterricht AS ltheo ON leist.id_flleist = ltheo.id_flleist

WHERE leist.id_nrmitar = 1
AND leist.lsdate BETWEEN '2017-06-01 00:00:00' AND '2017-06-30 23:59:59'
GROUP BY
leist.id_nrmitar,
leist.lsdate
ORDER BY leist.lsdate DESC) AS x

INNER JOIN davidw2000._mtbl_stammdaten AS Stamm ON x.id_nrmitar = Stamm.id_mitar
INNER JOIN davidw2000._sys_anrede AS Anr ON Stamm.id_anrnr = Anr.id_anrnr
[SQL]
 
Zuletzt bearbeitet von einem Moderator:
Moin Technic1965,

du hast doch die Lösung eigentlich schon skizziert.

"....
in der kde_leist Tabelle einträge der kunden sind die in einem 90 min unterricht waren,
wenn im unterricht 5 kunden waren dann bekommt man 5x90 also 450 min statt 90 min,"

Du darfst also nicht die gesamten "konsumierten" Minuten aller Kunden heranziehen, sondern nur die erteilten Stunden des Fahrlehrers.
Kommt jetzt auf die Tabellenstruktur an.
Vermutlich steht doch in der Tabelle, in der die Unterrichtsteilnehmer stehen, doch auch entweder eine ID für die konkrete Unterrichtsstunde/Unterrichtseinheit und/oder die von/bis-Zeit.

Also schematisch vermutlich die Informationen für die Fahrschüler Hinz, Kunz und Karl

01.06.2017 UnterrichtsID=33 Teilnehmer=Hinz Von 17:30 bis 19:00 (-- und in der Childtabelle stehen deshalb 90min)
01.06.2017 UnterrichtsID=33 Teilnehmer=Kunz Von 17:30 bis 19:00 (-- und in der Childtabelle stehen deshalb 90min)
01.06.2017 UnterrichtsID=33 Teilnehmer=Karl Von 17:30 bis 19:00 (-- und in der Childtabelle stehen deshalb 90min)
01.06.2017 UnterrichtsID=34 Teilnehmer=Kunz Von 19:30 bis 21:00 (-- und in der Childtabelle stehen deshalb 90min)
01.06.2017 UnterrichtsID=34 Teilnehmer=Karl Von 19:30 bis 21:00 (-- und in der Childtabelle stehen deshalb 90min)

Richtig wäre hier also nicht die 5x90 Minuten aus der Childtabelle, sondern insgesamt 2x90 erteilte Minuten bzw. zwei erteilte Theoriestunden

Also wäre der Weg z.B. die Summe aller distincten von/bis-Zeiten oder Anzahl distincter UnterrichtsIds (falls alle Unterrichtsblöcke immer gleich lang dauern)
Ist also lösbar, aber dazu müsste man den Tabellenaufbau kennen.
Kann ja etwas anders aussehen, als ich mir den zusammenphantasiert habe.

Grüße
Biber
 
Hi Biber,
klappt bei mir nicht :) so sollte es aussehen
upload_2017-8-11_1-22-59.png

Aber Blödsinn kommt
upload_2017-8-11_1-25-10.png

Mache ich das, dann ist es richtig, dann bekomme ich aber keine Ergebnisse für die weiteren abfragen
upload_2017-8-11_1-26-31.png

Die Tabellen sehen so aus

upload_2017-8-11_1-30-48.pngupload_2017-8-11_1-22-59.png upload_2017-8-11_1-25-10.png upload_2017-8-11_1-26-31.png upload_2017-8-11_1-30-48.png
 

Neue Beiträge

Zurück