2017-01-21 11 views
-1

Hier sind 4 Tische ....Wie kann ich diese SQL-Abfrage optimieren?

  1. tbl_std_working_hour
  2. tbl_attendance
  3. tbl_holiday
  4. tbl_leave

Ich möchte von dieser Abfrage die Mitarbeiter abwesenden Berichte, um herauszufinden, ... .aber es dauert Zeiten, wenn ich dies für viele Mitarbeiter angewendet habe ... gibt es eine Möglichkeit, diese Abfrage zu vereinfachen?

SELECT date 
FROM tbl_std_working_hour 
WHERE date NOT IN (SELECT date FROM tbl_attendance WHERE emp_id = '$emp_id') 
AND date NOT IN (SELECT date FROM tbl_holiday) 
AND date NOT IN (SELECT date FROM tbl_leave WHERE emp_id = '$emp_id') 
AND total_hour <> '00:00:00' 
AND date >= '$start' 
AND date <= '$end' 
AND emp_id = '$emp_id' 
+0

Siehe http://meta.stackoverflow.com/questions/333952/why-should-i-provide-an-mcve-for mit -was-scheint-zu-mir-ein-sehr-einfach-sql-Abfrage – Strawberry

Antwort

2

Zuerst würde ich NOT EXISTS neu schreiben mit:

SELECT wh.date 
FROM tbl_std_working_hour wh 
WHERE NOT EXISTS (SELECT 1 
        FROM tbl_attendance a 
        WHERE a.date = wh.date AND a.emp_id = wh.emp_id 
       ) AND 
     NOT EXISTS (SELECT 1 
        FROM tbl_holiday h 
        WHERE h.date = wh.date 
       ) AND 
     NOT EXISTS (SELECT 1 
        FROM tbl_leave l 
        WHERE l.emp_id = wh.emp_id and l.date = wh.date 
       ) 
WHERE wh.total_hour <> '00:00:00' AND 
     wh.date >= '$start' AND 
     wh.date <= '$end' AND 
     wh.emp_id = '$emp_id'; 

Dann fügen Sie den folgenden Composite (mehrspaltige) Indizes:

  • tbl_std_working_hour(emp_id, date, total_hour)
  • tbl_attendance(emp_id, date)
  • tbl_holiday(date) (vielleicht schon existieren, wenn date der Primärschlüssel oder einzigartig ist)
  • tbl_leave(emp_id) (möglicherweise bereits existiert, wenn emp_id den Primärschlüssel oder einzigartig ist)

Bitte beachte, dass ich die Subqueries verändern die emp_id in der äußeren Abfrage zu verweisen. Dies macht es einfacher, die emp_id zu ändern. Darüber hinaus sollte Ihre Abfrage Parameter für die Werte in der WHERE-Klausel verwenden.

+1

Es funktioniert nicht ..... !! :( – Kabir

+0

@Kabir.. "Nicht funktioniert" ist ziemlich vage. Sie sollten genauer über das Problem sein. –

0

Dies ist auch eine bessere Möglichkeit, die besser funktionieren kann UNION ALL

SELECT date 
FROM tbl_std_working_hour AS tswh 
WHERE NOT EXISTS(
    SELECT date FROM tbl_attendance ta WHERE ta.date = tswh.date AND ta.emp_id = tswh.emp_id 
    UNION ALL 
    SELECT date FROM tbl_holiday th WHERE th.date = tswh.date 
    UNION ALL 
    SELECT date FROM tbl_leave tl WHERE tl.date = tswh.date AND tl.emp_id = tswh.emp_id) 
AND total_hour <> '00:00:00' 
AND date >= '$start' 
AND date <= '$end' 
AND emp_id = '$emp_id' 
+0

tbl_holiday enthält keine emp_id ..... so gibt es Fehler wie # 1054 - Unbekannte Spalte 'th .emp_id 'in' where clause ' – Kabir

+0

Aktualisiert bitte überprüfen. – Susang

+0

@Suraz. Eigentlich ist' union all 'nicht besser, weil es wahrscheinlich die Verwendung von Indizes für die einzelnen Tabellen (in MySQL) ausschließen wird. –