2017-10-13 54 views
2

我試圖顯示每個城市中薪酬最低的員工的姓氏。城市列屬於名爲LOCATIONS的表格,而員工信息(薪水,姓氏)屬於僱員。這兩個表都相關共享沒有公共表,所以我必須依靠第三個表DEPARTMENTS來連接這兩個表,因爲DEPARTMENTS包含與EMPLOYEES共享的department_id以及與LOCATIONS共享的LOCATION_ID。這是我迄今爲止所做的,但是我在這方面遇到了麻煩,因爲我以前只使用過兩張桌子。使用3個表的子查詢SQL

SELECT LAST_NAME 
FROM EMPLOYEES 
WHERE (DEPARTMENT_ID) IN 
(SELECT DEPARTMENT_ID 
FROM DEPARTMENTS 
WHERE LOCATION_ID IN 
(SELECT LOCATION_ID 
FROM LOCATIONS 
GROUP BY CITY 
HAVING MIN(SALARY))); 

回答

0

您應該從WHERE子句中分離出表連接的概念。 使用WHERE過濾數據,使用JOIN將數據連接在一起。

我認爲這就是你想要的。順便說一句,如果可以的話,就丟掉所有的大寫字母。

SELECT 
    LAST_NAME 
FROM 
    EMPLOYEES 
    INNER JOIN (
     SELECT 
      DEPARTMENTS.DEPARTMENT_ID, 
      CITY, 
      MIN(SALARY) AS LOWEST_SALARY 
     FROM 
      EMPLOYEES 
      INNER JOIN DEPARTMENTS ON EMPLOYEES.DEPARTMENT_ID = DEPARTMENTS.DEPARTMENT_ID 
      INNER JOIN LOCATIONS ON DEPARTMENTS.LOCATION_ID = LOCATIONS.LOCATION_ID 
     GROUP BY 
      DEPARTMENTS.DEPARTMENT_ID, 
      LOCATIONS.CITY 
    ) AS MINIMUM_SALARIES 
    ON EMPLOYEES.DEPARTMENT_ID = MINIMUM_SALARIES.DEPARTMENT_ID 
     AND EMPLOYEES.SALARY = MINIMUM_SALARIES.LOWEST_SALARY 
+0

由於使用了別名,MINIMUM_SALARIES上的連接應該在「LOWEST_SALARY」上。 –

+0

所有大寫字母都是Oracle中的標準。 – Twelfth

+1

這也可以按城市返回多個最低工資,因爲它也是由'Department_ID'分組的。這意味着您可以接收來自同一城市的多個員工,這些員工等於他們的城市最低薪水。只需從子查詢中刪除「Department_ID」並加入外部的城市表格 –

2

這似乎是SQL中的一個介紹過程中的一項任務。因此,讓我們假設您不能使用分析函數,match_recognize子句等。只需加入並彙總。

在下面WHERE子句的子查詢中,我們計算每個城市的最低工資。我們需要參加這三個表。然後在整個查詢中,我們再次加入這三個表,並且我們使用IN條件(半連接)的子查詢。整體查詢如下所示:

select e.last_name 
from employees e join departments d 
        on e.department_id = d.department_id 
        join locations l 
        on d.location_id = l.location_id 
where (e.salary, l.city) in 
     (
     select min(salary), city 
     from  employees e join departments d 
           on e.department_id = d.department_id 
           join locations l 
           on d.location_id = l.location_id 
     group by city 
     ) 
; 
0

首先加入表格,以便您將城市和員工看成一排。如果我們按城市分組,我們會得到每個城市的最低工資。

with city_employees as 
(
    select l.city, e.* 
    from locations l 
    join departments d using (location_id) 
    join employees e using (department_id) 
) 
select last_name 
from city_employees 
where (city, salary) in 
(
    select city, min(salary) 
    from city_employees 
    group by l.city 
); 

這是比較容易實現相同,但是,與窗口函數(min overrank over這裏)。

select last_name 
from 
(
    select 
    e.last_name, 
    e.salary, 
    min(e.salary) over (partition by l.city) as min_salary 
    from locations l 
    join departments d using (location_id) 
    join employees e using (department_id) 
) 
where salary = min_salary; 
+0

哎呀,我只是注意到,這與二十分鐘前的mathguy給出的答案是一樣的。抱歉。 –

+0

大聲笑 - 答案下有一個'delete'鏈接,可以用於這種情況。 – mathguy

+0

我看到你使用了WITH子句,在這裏它非常有意義,因爲同一個連接使用了兩次。我雖然也這樣做了,但我不知道在SQL入門課程中有多早,他們介紹了WITH子句。 – mathguy