如何以编程方式创建JOIN语句?

时间:2011-07-14 16:36:24

标签: c# .net sql sql-server-2008

技术:VS.net 2008,C#,Winforms,SQL Server 2008

我目前正在编写Visual Select Query构建器以进行工作,但我仍然坚持如何创建连接。我理解当我手动编写它们时我需要做什么,但我不确定如何将其转换为算法。

目前,我的选择查询构建器具有获取表,显示列,选择所需列的所有功能,在特定列上使用“AND,OR”语句,并且运行查询就好了。但是,一旦涉及另一张桌子,所有地狱都会破裂。

使用现有的应用程序是不可能的,并且答案表明其他产品应该被投票。

是否有一条严格的规则说“在撰写Join语句时,你应该做 __和__ 等等......”

我的初始概念基于MS Access,我注意到它使用了所有左连接,但我不明白为什么会这样做。

2 个答案:

答案 0 :(得分:1)

您想要了解的基本标准:

  • 哪些字段与表格相关?
  • 哪些字段有不等价?
  • 您是否只想将结果数量限制为匹配,或者包括不匹配?

第一个标准对您的ON声明很重要。第二个也是。有一个查询,你希望看到的结果有一些共同的字段,但其他字段不是,这一点并不罕见,例如:

SELECT a.LineId, a.Total, b.Subtotal
FROM TableA as A
INNER JOIN TableB as B
    ON b.subtotal = a.total
    AND b.ID <> a.LineId

第三个标准是您如何知道自己是LEFT还是INNER JOIN

如果您只想查看匹配的行,请使用INNER。如果要查看第一个表中的所有行,但显示第二个表中存在的匹配项,请使用LEFT JOIN

您可能还需要考虑FULL OUTER联接,它们会显示两个表的所有结果。 CROSS JOIN没有被广泛使用,因此您需要确定是否有用例。它们显示了笛卡尔积(即表A中的所有行与表B中的所有行匹配 - 所有可能的组合)。

你能更具体地了解你的需求吗?

答案 1 :(得分:1)

这种事情没有“硬性和快速”的规则,因为它在很大程度上取决于数据的结构。我认为你已经开始关注MS Access如何处理它了。其他好的选择是在设计器中创建一些示例Entity Framework或LINQ 2 SQL模型,并观察它们如何在后端转换为SQL。 (尤其是EF的联合设计师非常聪明且灵活。)

Access主要使用左连接,因为它们是“最安全的”,因为它对源数据结构完全不了解。诀窍是尝试设计一个与用户期望的工具相匹配的工具。在Access的查询设计器中,如果我选择一个表,然后将其连接到另一个表,最可能的情况是“我想要从该表中获取所有数据但我需要从其他表中提取数据”,这是一个左加入。如果产生了一个内连接,并且我最终没有得到第一个表中的所有行,那可能会令人惊讶。

当然,如果您确实需要,Access还允许您修复这些规则。这是最好的方法:产生一个最不可能混淆用户的合理默认值,然后为他们提供一种方法来改变默认值,如果他们知道的更好。

一种选择是将连接语言翻译成略高的级别;例如,如果您的用户完全熟悉数据建模,他们可能会识别“一对多”(内部联接)与“一对多或更多”(外部联接)。甚至可能使在构建器中创建连接的操作使用完全不同的单词,例如“Optional Link”与“Required Link”甚至“Connect Lookup Table”与“Merge Child Data”。在使用查询设计器时,找出用户在脑海中想到的单词或术语,将它们映射到适当的JOIN类型,然后使用它们。同样,EF设计者已将连接的SQL概念映射到更好的父/子关系的数据建模概念。

从技术角度来看,我有关于编写JOIN的个人规则。其中一些是基于可能过时或过时的如何优化查询和索引的想法,可能不再严格需要,但对我有用:

  • 始终使用长格式连接语法(没有WHERE子句快捷方式
  • 尽可能将子表行中的所有条件放入ON子句中(也就是说,我的WHERE子句很少包含包含内连接表中字段的条件)
  • 使用INNER JOIN,知道哪里是安全的
  • 在可能的情况下,首选LEFT JOINS并且不对子查询为空。
编辑:我已经纠正了错误的看法,即JOINS比子查询执行得更快。 (当然,无论如何你都要进行自己的性能测试,对吧?:))