2016-12-11 5 views
0

Mit der folgenden Frage könnten Sie mir bitte erklären, was der Unterschied zwischen den zwei SQL ist und warum sie nicht das gleiche Ergebnis haben?Warum eine Abfrage mehr als andere zurückgibt

Zeigen Sie den Nachnamen, den Abteilungsnamen und das Gehalt eines Mitarbeiters an, dessen Gehalt und Provision mit dem Gehalt und der Provision eines Mitarbeiters in Position ID1700 übereinstimmen.

SELECT E.LAST_NAME, D.DEPARTMENT_NAME, E.SALARY 
    FROM EMPLOYEES E 
    JOIN DEPARTMENTS D 
    ON (E.DEPARTMENT_ID =D.DEPARTMENT_ID) 
    WHERE E.SALARY IN (SELECT SALARY 
         FROM EMPLOYEES 
         WHERE D.LOCATION_ID = 1700) AND 
     E.COMMISSION_PCT IN (SELECT COMMISSION_PCT 
           FROM EMPLOYEES 
           WHERE D.LOCATION_ID = 1700); 

(0 Ausgänge)

und

SELECT e.last_name, d.department_name, e.salary 
    FROM employees e, 
     departments d 
    WHERE e.department_id = d.department_id AND 
     (salary, NVL(commission_pct,0)) IN (SELECT salary, 
                NVL(commission_pct,0) 
               FROM employees e, 
                departments d 
               WHERE e.department_id = d.department_id AND 
                d.location_id = 1700); 

(36 Ausgänge)

+0

Welche Datenbank verwenden Sie eigentlich? Ich vermute, Oracle, und ich vermute, das ist ein Hausaufgabenproblem. –

+0

Ja, Oracle DB. Ich versuche herauszufinden, warum die 0 Ausgänge nicht funktionieren. (Ich schrieb das selbst). Die Lösung für die Frage ist die mit den 36 Ausgängen. Ich weiß nicht, warum der SQL-i-Typ nicht korrekt ist, sieht für mich korrekt aus, basiert aber anscheinend nicht auf Ergebnissen. –

+0

Fügen Sie einige Beispieltabellendaten und die aktuellen zwei Ergebnisse hinzu. (Auch formatierter Text.) Zeigen Sie uns auch das gewünschte Ergebnis. – jarlh

Antwort

2

Hinweis, dass diese Abfrage:

SELECT e.last_name, d.department_name, e.salary 
    FROM employees e, 
     departments d 
    WHERE e.department_id = d.department_id AND 
     (salary, NVL(commission_pct,0)) IN (SELECT salary, 
                NVL(commission_pct,0) 
               FROM employees e, 
                departments d 
               WHERE e.department_id = d.department_id AND 
                d.location_id = 1700); 

... gehören beliebige Mitarbeiter, der das gleiche hat Lohn und Provision als jemand in Standort 1700. Folglich werden alle Mitarbeiter in Standort 1700 in die Ergebnismenge einbezogen. Aber auch andere Mitarbeiter, nicht an diesem Standort, könnten gefunden werden, wenn nur jemand in Standort 1700 genau das gleiche Gehalt und die gleiche Provision hat. Diese Abfrage antwortet also korrekt auf die gegebene Zuweisung. Die andere Abfrage hat jedoch eine ungerade Bedingung in beiden Unterabfragen, da sie eine Bedingung auf die äußere Abfrage anwendet (die einzige Stelle, an der definiert ist) - nicht die Unterabfrage - und zwar zweimal (was nicht hilft):

SELECT E.LAST_NAME, D.DEPARTMENT_NAME, E.SALARY 
    FROM EMPLOYEES E 
    JOIN DEPARTMENTS D 
    ON (E.DEPARTMENT_ID =D.DEPARTMENT_ID) 
    WHERE E.SALARY IN (SELECT SALARY 
         FROM EMPLOYEES 
         WHERE D.LOCATION_ID = 1700) AND 
     E.COMMISSION_PCT IN (SELECT COMMISSION_PCT 
           FROM EMPLOYEES 
           WHERE D.LOCATION_ID = 1700); 

Sie würden nichts wesentlich ändern, wenn Sie diese Bedingung auf location_id in der äußeren where Klausel bewegen würden. Und jetzt wird klar, dass diese Abfrage keine Mitarbeiter ausschließt, die nicht in Standort 1700 sind - das gilt nicht immer für die andere Abfrage.

Darüber hinaus diese nicht die NVL Funktion hat angewendet commission_pct, was bedeutet, dass auch dann ausgeschlossen werden, wenn sie Mitarbeiter null als commission_pct haben. Dies liegt daran, NULL IN (SELECT ...)immer wertet zu false.

So gibt es zwei Gründe, warum diese Abfrage weniger Datensätze zurückgeben kann, und auch, warum es die falsche Antwort auf die Aufgabe ist, die Sie erhalten haben.

+0

Dank Sir, gibt es eine einfachere Möglichkeit, die Abfrage mit meiner Methode neu zu schreiben? Möglich, ein JOIN zu verwenden? Und ich verstehe nicht wirklich was "Sie würden nichts Wesentliches ändern, wenn Sie diese Bedingung auf location_id in der äußeren where-Klausel verschieben würden." meine ... –

+0

Entschuldigung, ich dachte, Ihre Frage war * "Was ist der Unterschied zwischen den beiden SQLs und warum haben sie nicht das gleiche Ergebnis? "*. Jetzt fragen Sie, um die Abfrage neu zu schreiben? Wenn das Ihre Frage ist, bitte eine neue Frage (kein Problem). Mein Kommentar zu der Bedingung auf' location_id 'bedeutet, dass diese Bedingung nichts auf verweist in die Unterabfrage und ist daher ziemlich irreführend. Es ist eine Bedingung für die äußere Abfrage, also sollte es dort eingefügt werden. Und ich sage, dass solch eine Bewegung das Ergebnis nicht ändern würde. Aber es verdeutlicht besser, was passiert. – trincot

Verwandte Themen