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



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

我目前正在编写一个Visual Select Query构建器,但我对如何创建联接感到困惑。当我手动编写它们时,我理解我需要如何做,但我不确定如何将其转化为算法。

目前,我的选择查询生成器具有获取表、显示列、选择所需列、对特定列使用"AND,OR"语句的所有功能,并且可以很好地运行查询。但一旦涉及到另一张桌子,一切都会变得一团糟。

使用现有的应用程序是不可能的,建议其他产品应该被否决

是否有一条硬性规定:"在编写Join语句时,您应该执行__和__等……)

我最初的概念是基于MS Access的,我注意到它使用了所有剩下的Joins,但我不明白它为什么这么做。

您想要了解的基本标准:

  • 哪些字段使表相关
  • 哪些字段具有等价性
  • 是否将结果数限制为仅匹配项,还是包括不匹配项

第一个标准对于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中的所有行都匹配——所有可能的组合)。

你能更具体地说明你需要什么吗?

这类事情没有"硬性"规则,因为它在很大程度上取决于数据的结构。我认为你已经开始观察MS Access如何处理它了。其他好的选择是在设计器中创建一些示例实体框架或LINQ 2 SQL模型,并观察这些模型是如何在后端转换为SQL的。(特别是英孚的加盟设计师,非常聪明和灵活)。

Access主要使用左联接,因为在完全不了解源数据结构的情况下,它们是"最安全的"联接。诀窍是尝试设计一个符合用户期望的工具。在Access的查询设计器中,如果我选择一个表,然后将其连接到另一个表上,最有可能的情况是"我想要这个表中的所有数据,但我也需要从另一个表格中提取数据",这是一个左联接。如果生成了一个内部联接,而我最终没有将第一个表中的所有行都取回,那可能会令人惊讶。

当然,如果你真的需要,Access也允许你修改这些规则。这是最好的方法:生成一个合理的默认值,最不可能让用户感到困惑,然后如果他们更清楚,就为他们提供一种更改默认值的方法。

一种选择是将联接语言翻译成稍高级别的语言;例如,如果用户完全熟悉数据建模,他们可能会识别"一对多"(内部联接)与"一对零或更多"(外部联接)。甚至可能使在构建器中创建联接的操作使用完全不同的词语,例如"可选链接"与"必需链接",甚至"连接查找表"与"合并子数据"。找出用户在使用查询设计器时脑子里想的单词或术语,将它们映射到适当的JOIN类型,然后使用它们。同样,EF设计者已经将连接的SQL概念映射到了更高级别的父/子关系数据建模概念上,该概念运行良好。

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

  • 始终使用长格式联接语法(无WHERE子句捷径
  • 尽可能将子表行上的所有条件放入on子句中(也就是说,我的WHERE子句很少有包含内部联接表中字段的条件)
  • 在已知安全的地方使用INNER JOIN
  • 如果可能的话,子查询更喜欢LEFT JOIN和IS NOT NULL

EDIT:我已经纠正了我的错误看法,即JOIN比子查询执行得更快。(当然,你无论如何都要自己做性能测试,对吧?:)

最新更新