避免在连接中选择同名列

时间:2016-04-04 21:33:34

标签: sql join sybase

TABLE_A:  columns id, colA1, colA2, ...
TABLE_B:  columns id, colB1, colB2, ...

QUERY1:   SELECT *
          FROM TABLE_A, TABLE_B
          WHERE TABLE_A.id = TABLE_B.id
-- This works perfectly

QUERY2:   SELECT *
          INTO #tempT
          FROM TABLE_A, TABLE_B
          WHERE TABLE_A.id = TABLE_B.id
-- This fails because A.id and B.id have same column name in SELECT
-- ERROR: Column names in each table must be unique.

解决查询#2问题的一种明显方法是明确选择TABLE_B中的所有非ID列:

QUERY3: SELECT TABLE_A.*, TABLE_B.colB1, TABLE_B.colB2, ...

该方法的问题是2倍,并且实际上是将SELECT列的精确列表硬编码到SELECT查询中的一般问题:

  1. 对列进行硬编码会使代码在以后添加了更多列的表中变得脆弱。每次向TABLE_B添加列时,都需要使用给定的查询更改,重新测试和重新发布代码。

  2. 如果表中有很多列,查询看起来很糟糕,并且由于SELECT语句过长而难以阅读

  3. 是否有针对查询#2的问题的Sybase SQL特定解决方案,这避免了查询#3的问题?

    我正在寻找使用Sybase SQL的解决方案。不适用:涉及使用应用程序代码读取表结构并构造上面的查询#3的解决方案。也不是在Sybase中使用eval的解决方案。

1 个答案:

答案 0 :(得分:1)

简短回答:

答案很长:

您不会喜欢它,但答案是在您创作查询时不使用*。

在编写代码以使用结果时,指定要选择的列是理想的,以便您知道哪些列是返回的数据集的一部分。与您所说的相反,未指定选定的列会使下游流程变得脆弱,因为如果有人向表中添加了列,则会在结果数据集中显示意外的列。如果您在select中指定了每个列,那么无论何时向表中添加列,现有报表或视图都会像以前一样工作。

此外,关键列不一定是唯一含糊不清的列;如果您有两个在ID上键入的表,但也有一个名称列(Say,学生表和教师表),那么即使从select中排除ID列,您也会出现列歧义。但是,这两个列在您要查找的结果集中可能很重要。

不是Sybase SQL特定的,但MSDN对Choosing All Columns

提出了这种警告
  

如果在具有依赖于结果集中列数的逻辑的应用程序或脚本中使用SELECT,则最好指定选择列表中的所有列,而不是指定星号。如果稍后将列添加到SELECT语句引用的表或视图中,则在单独列出列时,应用程序将不受更改的影响。如果指定了星号(*),则新列将成为结果集的一部分,并可能影响应用程序或脚本的逻辑。您应该避免使用星号(*),尤其是对目录视图,动态管理视图和系统表值函数。 Microsoft SQL Server的未来升级和发布可能会添加列并将列的顺序更改为这些视图和函数。这些更改可能会破坏期望特定订单和列数的应用程序。