我对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的表格,因为
从哪个表中得到它无关紧要
我几乎说过,我想通过SELECT Worker.id FROM Worker
除了编写SELECT Worker.id FROM Worker
之外,还有更好的方法来定义我想要id的表格,因为我感觉好像我以某种方式重复了自己
答案 0 :(得分:3)
这取决于每个数据库提供程序如何处理自己的查询语法,但这是我的想法:
1)从哪个表中得到它无关紧要
在您的示例中可能无关紧要,但数据类型不匹配的实例(int/smallint
,date/datetime
,int/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_A
和table_B
),表明记录何时被插入表中。现在你告诉DB:"嘿,加入table_A
和table_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引擎如何知道在这样的实例中提供哪个值?就个人而言,我喜欢它需要该特定产品中的别名。