建议的方式来编写数据库查询

时间:2013-08-01 09:25:21

标签: sql database database-design

这个数据库查询有什么问题

select 
    abstract_author.name, 
    title, 
    affiliation_number,
    af_name 
from        
    abs_affiliation_name, 
    abstract_affiliation,
    abstracts_item,
    abstract_author,
    authors_abstract 
where 
    abstracts_item._id = authors_abstract.abstractsitem_id and  
    abstract_author._id = authors_abstract.abstractauthor_id and 
    abstract_affiliation._id = abstract_author._id and  
    abs_affiliation_name._id =  abstracts_item._id 

我得到了预期的结果。但是,有人说这不是推荐的方式或者是一种好的做法。你能告诉我什么是建议的方式来编写我的查询(我的意思是哪些有连接)?

3 个答案:

答案 0 :(得分:1)

不建议在where子句中进行连接。相反,使用显式JOIN条件会更好。所以你的查询将是

SELECT
  abstract_author.name
, title
, affiliation_number
, af_name 
FROM abstracts_item
JOIN authors_abstract ON abstracts_item._id = authors_abstract.abstractsitem_id
JOIN abstract_author ON abtract_author.id = authors_abstract.abstractauthor_id
JOIN abstract_affiliation ON abstract_affiliation._id = abstract_author._id
JOIN abs_affiliation_name ON abs_affiliation_name._id = abstracts_item.id

我强烈建议您在桌子上使用别名,但这样可以避免混淆。在此示例中,如果您向其他表之一引入了title字段,则查询很可能会中断,因为它知道要定位哪个表。我做了类似

的事情
SELECT
  au.name
, af.title
, af.affiliation_number
, af.af_name 
FROM abstracts_item ai
JOIN authors_abstract aa ON ai._id = aa.abstractsitem_id
JOIN abstract_author au ON au.id = aa.abstractauthor_id
JOIN abstract_affiliation af ON af._id = au._id
JOIN abs_affiliation_name an ON an._id = ai.id

您需要更改选择位中的别名,但我已经猜到了他们来自哪些表

答案 1 :(得分:0)

我建议您使用joinaliases,如下所示

select aath.name, /*alias*/title, /*alias*/affiliation_number,/*alias*/af_name 
from abs_affiliation_name aan
join abstracts_item ai on aan._id =  ai._id     
join abstract_affiliation aa on  aa._id = aath._id 
join authors_abstract  aAbs on ai._id = aAbs.abstractsitem_id 
join abstract_author aath on aath._id = aAbs.abstractauthor_id 

答案 2 :(得分:0)

您的查询没有错误。这是个人偏好,您使用的ANSI-89 impicit连接已经过时了20多年,它们在ANSI-92中被替换为显式JOIN语法。

Aaron Bertrand写了一个compelling article,说明为什么在大多数情况下优先使用较新的连接语法,以及使用ANSI-89连接的潜在缺陷。在大多数情况下,两种方法的执行计划将完全相同(假设您没有意外地与implict连接交叉连接)。值得注意的是,尽管Oracle会产生不同的执行计划,但ANSI-89连接语法可以产生更高效的两者。 (我已经看到了一个回复我的答案的例子,但我现在找不到它,你现在必须接受我的话)。但是,我不会将此作为始终使用ANSI-89连接的理由,使用ANSI-92连接语法的另一个关键原因是外部连接可以使用ANSI语法实现,而隐式连接的外部连接语法因DBMS而异

e.g。在Oracle上

SELECT  *
FROM    a, b
WHERE   a.id = b.id(+)

在SQL-Server上(不建议使用)

SELECT *
FROM    a, b
WHERE   a.id *= b.id

但是,以下内容适用于:

SELECT  *
FROM    a
        LEFT JOIN b
            ON a.id = b.id

如果你总是使用显式连接,那么你最终会得到更一致的(在我看来更具可读性)查询。