使用3个表SQL

时间:2017-10-13 20:06:53

标签: sql oracle subquery

我试图显示每个城市中收入最低的员工的姓氏。城市专栏属于名为LOCATIONS的表格,而员工信息(薪水,姓氏)属于EMPLOYEES。这两个表都是相关的共享没有公共表,所以我必须依赖第三个表,DEPARTMENTS来连接两个,因为DEPARTMENTS包含它与EMPLOYEES共享的department_id以及它与LOCATIONS共享的LOCATION_ID。这就是我到目前为止所做的事情,但我遇到了麻烦,因为我过去只使用过两张桌子。

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

3 个答案:

答案 0 :(得分: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
       )
;

答案 1 :(得分:0)

您应该从WHERE子句中分离出表连接的概念。 使用WHERE过滤数据,使用JOIN将数据连接在一起。

我认为这就是你想要的。顺便说一下,如果可以的话,就失去ALL CAPS。

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

答案 2 :(得分: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;