SQL 查询 INTERSECT 来自相同 table 的两列:

SQL query to INTERSECT two columns from same table:

我有 table 名员工,如下所示:

column_name   | column_id |
employee_id   |     1     |
first_name    |     2     |
last_name     |     3     |     
department_id |     11    |

Employees Table 也有一个引用 Departments Table 上的主键的外键:

column name   | column id |    
department_id |     1     |

我的目标是使用 INTERSECT 来显示同时用作名字和姓氏的所有员工姓名。 (即:如果 'Lee' 是名字和姓氏,我想具体显示他的名字)。

我正在显示部门 Table,因为我不确定是否需要 JOIN 才能获得我想要的结果。

首先,我得到了所有名字和姓氏的完整列表:

SELECT e.first_name, e.last_name
FROM Employees e

INTERSECT

SELECT e2.first_name, e2.last_name
FROM Employees e2;

但我只想要出现在 first_namelast_name 列中的名称。

我试过以下方法:

SELECT e.first_name, e.last_name
FROM Employees e
WHERE e.first_name = e.last_name

INTERSECT

SELECT e2.first_name, e2.last_name
FROM Employees e2
WHERE e2.first_name = e2.last_name;

没有选择任何行。

我也试过用 JOIN:

SELECT e.first_name, e.last_name
FROM Employees e
JOIN Departments d ON d.department_id = e.department_id

INTERSECT

SELECT e2.first_name, e2.last_name
FROM Employees e2
JOIN Departments d2 ON d2.department_id = e2.department_id;

这选择了所有行。

我也想知道是否有一种方法可以 INTERSECT 这些列而不使用 WHERE 子句?

这样的事情怎么样:

-- get intersection of first and last name sets
select distinct first_name as first_and_last_name from employees
intersect
select distinct last_name as first_and_last_name from employees;

或者这个:

-- get first names that are also last names
select distinct first_name from employees
where first_name in (select distinct last_name from employees);

没有理由担心 department table 除非您想在结果集中包含来自 table 的数据或使用它来过滤结果集。

它有助于建立您的查询 step-by-step。

我们首先获取名字和姓氏的列表。这就是您的 INTERSECT 发挥作用的地方。

SELECT e.first_name
FROM   employees e
INTERSECT
SELECT e.last_name
FROM   employees e;

现在,您有了该列表。接下来,您想要显示名字或姓氏在该列表中的任何员工的员工详细信息。将其视为“在何处(某些标准)显示员工详细信息”。我们将从员工详细信息查询开始,稍后添加条件,其中将包括上面的 INTERSECT 查询。

因此,员工详细信息的基本查询为:

SELECT e.first_name, e.last_name, d.department_id
FROM   employees e
INNER JOIN departments d ON d.department_id = e.department_id
WHERE ???  -- we need to plug the first query in here somehow.

然后,把它放在一起...

SELECT e.first_name, e.last_name, d.department_id
FROM   employees e
INNER JOIN departments d ON d.department_id = e.department_id
WHERE  (
         e.first_name IN 
           ( SELECT e.first_name
             FROM   employees e
             INTERSECT
             SELECT e.last_name
             FROM   employees e )
OR       e.last_name IN 
           ( SELECT e.first_name
             FROM   employees e
             INTERSECT
             SELECT e.last_name
             FROM   employees e )
        )

注意我们已经重复了 INTERSECT 部分,重复是不好的,所以我们将把它变成一个常见的 table 表达式(想想“WITH 子句”)

WITH   names (name) AS
           ( SELECT e.first_name name
             FROM   employees e
             INTERSECT
             SELECT e.last_name name
             FROM   employees e )
SELECT e.first_name, e.last_name, d.department_id
FROM   employees e
INNER JOIN departments d ON d.department_id = e.department_id
WHERE  (
         e.first_name IN ( SELECT name FROM names )
OR       e.last_name IN ( SELECT name FROM names )
        )

类似的东西应该可以做到。

存在 :

SELECT first_name FROM employees e WHERE EXIST (SELECT * FROM employees ee WHERE ee.last_name = e.first_name)