SQL IN的工作难度

时间:2011-05-12 19:08:52

标签: mysql

我的理解是IN就像一个布尔函数,为每个实例返回一个值,当使用IN时,外部查询中的一行返回true。因此,结果集不应该只有外部查询的行数吗?

表1:

   DNUMBER DLOCATION
---------- ---------------
         1 Houston
         4 Stafford
         5 Bellaire
         5 Houston
         5 Sugarland

表2:

DNAME                   DNUMBER
-------------------- ----------
Research                      5
Administration                4
Headquarters                  1

那么这个查询不应该只返回3行吗?

SELECT D.dname, DL.dlocation
FROM department D, dept_locations DL
WHERE D.dnumber IN
(SELECT dnumber FROM dept_locations)

结果:

DNAME                DLOCATION
-------------------- -------------
Headquarters         Houston
Administration       Houston
Research             Houston
Headquarters         Stafford
Administration       Stafford
Research             Stafford
Headquarters         Bellaire
Administration       Bellaire
Research             Bellaire
Headquarters         Houston
Administration       Houston
Research             Houston
Headquarters         Sugarland
Administration       Sugarland
Research             Sugarland

3 个答案:

答案 0 :(得分:1)

SELECT D.dname, DL.dlocation
FROM department D, dept_locations DL
WHERE D.dnumber IN
(SELECT dnumber FROM dept_locations)

没有连接条件(显式或隐式)限制要以任何方式匹配的行,因此执行交叉连接(左侧的所有行组合和右侧的行)。

答案 1 :(得分:1)

您对IN的理解是正确的。您获得更多行的原因是因为您的主查询是从2个表中进行选择而对第二个表没有限制。此查询仅返回3行:

SELECT D.dname
FROM department D
WHERE D.dnumber IN
(SELECT dnumber FROM dept_locations)

但当然你会失去你的位置。通过向dept_locations子句添加FROM,您基本上是交叉连接表,并且您不会使用WHERE子句限制从第二个表返回的行,“仅限制department

中的行

要正确限制使用当前查询格式返回的行,您可以执行以下操作:

SELECT D.dname, DL.dlocation
FROM department D, dept_locations DL
WHERE D.dnumber IN
(SELECT dnumber FROM dept_locations)
AND DL.dnumber = D.dnumber

但获取所需数据的最佳方法可能是使用JOIN

SELECT D.dname, DL.dlocation
FROM department D
JOIN dept_locations DL on DL.dnumber = D.dnumber

答案 2 :(得分:0)

SELECT D.dname
     , GROUP_CONCAT(DL.dlocation)
  FROM department AS D 
 INNER 
  JOIN dept_locations AS DL 
    ON D.dnumber = DL.dnumber 
 GROUP 
    BY D.dname;

我做了一些假设,但我认为这将返回您想要获得的数据。它会抓住每种类型(研究等)以及逗号分隔的位置列表。

您的查询根本不需要子查询,只需要适当的连接条件。