想知道为什么这个查询会这样?

0 postgresql

我有一个emp表,其中包含架构和一些初始值,如下所示:

 emp_id | name | last_name | role_id 
--------+------+-----------+---------
      1 | hell | bell      |       1
      2 | well | tell      |       2
(2 rows)
Run Code Online (Sandbox Code Playgroud)

以及另一个role表,该emp表已在 上引用role_id。下面是role表格:

 role_id | role_name 
---------+-----------
       1 | tech
       2 | op
       3 | dev
(3 rows)
Run Code Online (Sandbox Code Playgroud)

我只是在玩,写了下面的查询,我认为这没有多大意义。

SELECT emp.name, role.role_name, emp.emp_id 
FROM emp 
INNER JOIN role 
    ON emp.role_id = (
        SELECT role_id from role WHERE role_name = 'tech'
    );
Run Code Online (Sandbox Code Playgroud)

它工作并返回了这个结果:

 name | role_name | emp_id 
------+-----------+--------
 hell | tech      |      1
 hell | op        |      1
 hell | dev       |      1
(3 rows)
Run Code Online (Sandbox Code Playgroud)

我想知道为什么我得到这个结果以及它是如何工作的?

dez*_*zso 5

根据您的数据,您的查询等效于以下内容:

SELECT emp.name, role.role_name, emp.emp_id 
FROM emp 
INNER JOIN role 
    ON emp.role_id = 1; -- because this is the role_id for 'tech'
Run Code Online (Sandbox Code Playgroud)

这意味着您没有定义关于如何连接两个表的条​​件。反过来,这会产生role(对返回哪些行没有任何限制)和emp(其中role_id是 1)的笛卡尔积。

再次重写查询,它实际上是一个CROSS JOIN

SELECT emp.name, role.role_name, emp.emp_id 
FROM emp 
CROSS JOIN role 
WHERE emp.role_id = 1;
Run Code Online (Sandbox Code Playgroud)

SQLFiddle上查看它们。

你可能想要的是

SELECT emp.name, role.role_name, emp.emp_id 
FROM emp 
INNER JOIN role 
    ON emp.role_id = role.role_id
WHERE emp.role_id = 1;
Run Code Online (Sandbox Code Playgroud)