0

次の質問を使用して、2 つの SQL の違いと、同じ結果が得られない理由を説明していただけますか?

場所 ID1700 にいる従業員の給与と歩合と一致する給与と歩合を持つ従業員の姓、部署名、および給与を表示します。

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 出力)

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出力)

4

1 に答える 1

2

このクエリは次の点に注意してください。

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);

... 場所 1700 の従業員と同じ給与と歩合を持つ従業員が含まれます。結果として、場所 1700 のすべての従業員が結果セットに含まれます。しかし、場所 1700 にまったく同じ給与と手数料を持っている人がいる場合にのみ、その場所にいない他の従業員も見つけることができます。したがって、このクエリは、指定された割り当てに対して正しく答えます。

Dただし、他のクエリには、サブクエリではなく、外側のクエリ (が定義されている唯一の場所) に条件を適用するという点で、両方のサブクエリに奇妙な条件があります。 ):

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);

location_idその条件を外側のwhere句に移動しても、実質的な変更はありません。これで、このクエリでは場所 1700 にない従業員が除外されることが明らかになりました。これは、他のクエリには常に当てはまるとは限りません。

NVLさらに、これには に適用される機能がありません。つまり、従業員がascommission_pctを持っている場合も除外されます。これは、常にfalse と評価されるためです。nullcommission_pctNULL IN (SELECT ...)

したがって、このクエリで返されるレコードが少なくなる理由と、取得した割り当てに対する間違った回答である理由が 2 つあります。

于 2016-12-11T10:11:54.160 に答える