INNER JOIN失败后的SELECT

时间:2017-09-22 15:59:07

标签: sql inner-join

我对SQL很陌生,在我看来,我遇到了一些奇怪的事情:

我有以下查询:

SELECT id 
FROM Worker
INNER JOIN Computer ON Worker.Id = Computer.Id

非常简单的东西。此查询将失败,我认为此查询失败是违反直觉的。

查询将失败,因为我将有2列名为id。我可以通过写:

来使查询工作
SELECT Worker.id 
FROM Worker
INNER JOIN Computer ON Worker.Id = Computer.Id

我的问题是:

为什么我的查询要求我说明我想要id的表格,因为

  1. 从哪个表中得到它无关紧要

  2. 我几乎说过,我想通过SELECT Worker.id FROM Worker

  3. 从'工人'表中找到它

    除了编写SELECT Worker.id FROM Worker之外,还有更好的方法来定义我想要id的表格,因为我感觉好像我以某种方式重复了自己

3 个答案:

答案 0 :(得分:3)

这取决于每个数据库提供程序如何处理自己的查询语法,但这是我的想法:

  

1)从哪个表中得到它无关紧要

在您的示例中可能无关紧要,但数据类型不匹配的实例(int/smallintdate/datetimeint/string)怎么办?或者,如果您使用的是left/right join而不是inner join?在这些情况下,数据库提供者必须做出选择。

  

2)我几乎说过我想从'工人'表中得到它   说SELECT Worker.id FROM

是的,您可以使用表格的顺序来解决歧义。这又是数据库提供商可以做出的决定。

  

是否有更好的方法来定义我想要id的表格   编写SELECT Worker.id FROM Worker因为我觉得好像我重复了一遍   我在某种程度上

我尽量避免使用inner joins进行过滤。相反,我会写这样的查询:

SELECT id FROM Worker where id in (select id FROM Computer)

SELECT id FROM Worker as w where exists (select 1 from Computer as c where c.id = w.id)

(这些可能不会返回与您的查询相同的结果,因为inner join可能会导致重复)

答案 1 :(得分:1)

  

此查询将失败,我认为此查询失败是违反直觉的。

我认为很清楚为什么查询会失败。至少我还没有看到数据库实现它不会失败(MySQL将失败并显示消息"列ID不明确" PostgreSQL将失败并显示消息" ERROR :列引用" id"不明确"并且MS-SQL将声明非常相似的内容),但可能存在不会失败的实现。

  

为什么我的查询要求我说明我想要id的表。

因为列id存在于两个表中。

  

1)从哪个表中得到它并不重要

你说的是什么,但数据库应该如何知道呢?想象一下,你有两个表中的时间戳(让他们称之为table_Atable_B),表明记录何时被插入表中。现在你告诉DB:"嘿,加入table_Atable_B,哦,请给我时间戳!"

DB如何知道您的时间戳是什么意思?

  

2)我几乎已经说过,我希望来自工作人员'表通过说SELECT id FROM Worker

你说你想要来自 Worker 的数据,加上来自 Computer 的数据!通过将两个表连接在一起,您将获得一个表。如果在多个表中出现行名,则必须明确说明每行的来源。回到上一个示例,如果table_A有一行名为 file_size table_B没有,那么就足以说明

SELECT file_size
FROM table_A
    JOIN table_B on table_A.id = table_B.id

因为只有一个列具有该名称。

  

除了编写SELECT Worker.id FROM Worker之外,还有更好的方法来定义我想要id的表,因为我感觉好像我在某种程度上重复了自己

Aducci提出的另一个可能的建议是使用别名,如下:

SELECT w.id
FROM Worker AS w
    INNER JOIN Computer AS c ON w.Id = c.Id

这样你就不必每次都输入整个表名。

答案 2 :(得分:1)

在SQL Server中,请注意此查询。

DECLARE @var1 date ='01/01/2017'
DECLARE @Var2 varchar(20)='01/01/2017'

if (@var1=@Var2)
BEGIN
    select 'match'
END

结果是它因为隐式数据转换而匹配。 SQL引擎如何知道在这样的实例中提供哪个值?就个人而言,我喜欢它需要该特定产品中的别名。