Oracle:WITH子句查询两个表
Oracle: WITH-clause querying two tables
使用 Oracle 数据库,我有两个 table:
Employees:
Employee_id | Number(6,0)
Last_name | Varchar2(20)
Hire_date | Date
Deparment_id| Number(4,0)
Job_history:
Employee_id | Number(6,0)
Start_date | Date
Deparment_id | Number(4,0)
我应该找到 - 使用 WITH 子句 - 目前在他们开始工作的同一部门工作的所有员工(hire_date = start_date 和相同的 department_id).我在子查询中使用 JOIN 轻松获得了正确的结果:
SELECT DISTINCT e.employee_id, e.last_name, e.hire_date,
e.department_id as current_dep, j.department_id as prev_dep
FROM hr.employees e
JOIN (SELECT employee_id, department_id, end_date, start_date
FROM hr.job_history ) j
ON e.employee_id = j.employee_id
WHERE e.department_id = j.department_id;
(右)输出:
不幸的是,WITH 子句让我遇到了麻烦,因为我不确定如何管理两个不同的 table(我在网上找到的大多数示例都只有一个 table)
--best try until now--
With find_emp as (SELECT hire_date, department_id
FROM hr.employees)
SELECT e.employee_id, e.last_name, e.department_id as curr_dep
FROM HR.employees e
WHERE e.hire_date IN (SELECT j.start_date
FROM hr.job_history j
JOIN hr.employees e
ON e.employee_id = j.employee_id);
(错误)输出:
我做错了什么?由于我是 SQL 的新手,我将不胜感激每一个提示。非常感谢您。
SQL WITH 子句创建 'virtual' tables,您可以在该子句下的后续查询中引用它们。这些 tables 在内存中的查询生命周期内存在。它们有点像视图。
您的示例不工作,因为您正在建立一个名为 find_emp
的虚拟 table,但是您没有使用它。
一个例子
WITH subquery AS (
SELECT col1 , col2, col3
FROM table1
WHERE col4=condition1
)
SELECT * FROM subquery;
希望对您有所帮助。
应该是字里行间的东西:
WITH start_dept AS
(
SELECT emp.employee_id, dept.deparment_id AS prev_dep
FROM employees emp
, job_history dept
WHERE emp.employee_id = dept.employee_id
AND emp.hire_date = dept.start_date
)
SELECT e.employee_id, e.last_name, e.hire_date, e.deparment_id AS current_dep, sd.prev_dep
FROM employees e
, start_dept sd
WHERE e.employee_id = sd.employee_id
AND e.deparment_id = sd.prev_dep;
(假设 Employees.deparment_id 是当前部门并且 Employees.hire_date 匹配 Job_history 中的 start_date)
如果您正在寻找具有相同工作的员工,这意味着该员工的 JOB_HISTORY table 中只有一个条目。
因此,你可以这样做。
CREATE table dept (department_id, department_name) AS
SELECT 1, 'IT' FROM DUAL UNION ALL
SELECT 2, 'MARKETING' FROM DUAL UNION ALL
SELECT 3, 'SALES' FROM DUAL;
CREATE TABLE employees (employee_id, first_name, last_name, department_id, sal) AS
SELECT 1, 'Alice', 'Abbot', 1, 100000 FROM DUAL UNION ALL
SELECT 2, 'Beryl', 'Baron', 1, 50000 FROM DUAL;
CREATE table job_history (employee_id,
department_id) AS
SELECT 1, 1 FROM DUAL UNION ALL
SELECT 2, 1 FROM DUAL UNION ALL
SELECT 2, 3 FROM DUAL;
WITH rws AS
(
SELECT
e.employee_id,
e.first_name,
e.last_name,
e.department_id,
d.department_name
FROM EMPLOYEES e join dept d on e.department_id = d.department_id
WHERE EMPLOYEE_ID IN
(SELECT EMPLOYEE_ID FROM JOB_HISTORY GROUP BY EMPLOYEE_ID HAVING COUNT(EMPLOYEE_ID) =1)
)
SELECT
employee_id,
first_name,
last_name,
department_id,
department_name
FROM rws;
EMPLOYEE_ID FIRST_NAME LAST_NAME DEPARTMENT_ID DEPARTMENT_NAME
1 Alice Abbot 1 IT
使用 Oracle 数据库,我有两个 table:
Employees:
Employee_id | Number(6,0)
Last_name | Varchar2(20)
Hire_date | Date
Deparment_id| Number(4,0)
Job_history:
Employee_id | Number(6,0)
Start_date | Date
Deparment_id | Number(4,0)
我应该找到 - 使用 WITH 子句 - 目前在他们开始工作的同一部门工作的所有员工(hire_date = start_date 和相同的 department_id).我在子查询中使用 JOIN 轻松获得了正确的结果:
SELECT DISTINCT e.employee_id, e.last_name, e.hire_date,
e.department_id as current_dep, j.department_id as prev_dep
FROM hr.employees e
JOIN (SELECT employee_id, department_id, end_date, start_date
FROM hr.job_history ) j
ON e.employee_id = j.employee_id
WHERE e.department_id = j.department_id;
(右)输出:
不幸的是,WITH 子句让我遇到了麻烦,因为我不确定如何管理两个不同的 table(我在网上找到的大多数示例都只有一个 table)
--best try until now--
With find_emp as (SELECT hire_date, department_id
FROM hr.employees)
SELECT e.employee_id, e.last_name, e.department_id as curr_dep
FROM HR.employees e
WHERE e.hire_date IN (SELECT j.start_date
FROM hr.job_history j
JOIN hr.employees e
ON e.employee_id = j.employee_id);
(错误)输出:
我做错了什么?由于我是 SQL 的新手,我将不胜感激每一个提示。非常感谢您。
SQL WITH 子句创建 'virtual' tables,您可以在该子句下的后续查询中引用它们。这些 tables 在内存中的查询生命周期内存在。它们有点像视图。
您的示例不工作,因为您正在建立一个名为 find_emp
的虚拟 table,但是您没有使用它。
一个例子
WITH subquery AS (
SELECT col1 , col2, col3
FROM table1
WHERE col4=condition1
)
SELECT * FROM subquery;
希望对您有所帮助。
应该是字里行间的东西:
WITH start_dept AS
(
SELECT emp.employee_id, dept.deparment_id AS prev_dep
FROM employees emp
, job_history dept
WHERE emp.employee_id = dept.employee_id
AND emp.hire_date = dept.start_date
)
SELECT e.employee_id, e.last_name, e.hire_date, e.deparment_id AS current_dep, sd.prev_dep
FROM employees e
, start_dept sd
WHERE e.employee_id = sd.employee_id
AND e.deparment_id = sd.prev_dep;
(假设 Employees.deparment_id 是当前部门并且 Employees.hire_date 匹配 Job_history 中的 start_date)
如果您正在寻找具有相同工作的员工,这意味着该员工的 JOB_HISTORY table 中只有一个条目。
因此,你可以这样做。
CREATE table dept (department_id, department_name) AS
SELECT 1, 'IT' FROM DUAL UNION ALL
SELECT 2, 'MARKETING' FROM DUAL UNION ALL
SELECT 3, 'SALES' FROM DUAL;
CREATE TABLE employees (employee_id, first_name, last_name, department_id, sal) AS
SELECT 1, 'Alice', 'Abbot', 1, 100000 FROM DUAL UNION ALL
SELECT 2, 'Beryl', 'Baron', 1, 50000 FROM DUAL;
CREATE table job_history (employee_id,
department_id) AS
SELECT 1, 1 FROM DUAL UNION ALL
SELECT 2, 1 FROM DUAL UNION ALL
SELECT 2, 3 FROM DUAL;
WITH rws AS
(
SELECT
e.employee_id,
e.first_name,
e.last_name,
e.department_id,
d.department_name
FROM EMPLOYEES e join dept d on e.department_id = d.department_id
WHERE EMPLOYEE_ID IN
(SELECT EMPLOYEE_ID FROM JOB_HISTORY GROUP BY EMPLOYEE_ID HAVING COUNT(EMPLOYEE_ID) =1)
)
SELECT
employee_id,
first_name,
last_name,
department_id,
department_name
FROM rws;
EMPLOYEE_ID FIRST_NAME LAST_NAME DEPARTMENT_ID DEPARTMENT_NAME
1 Alice Abbot 1 IT