【问题标题】:Use join column only once in SELECT * [duplicate]在 SELECT * [重复] 中仅使用一次连接列
【发布时间】:2026-02-05 19:25:02
【问题描述】:

假设:

WITH t12 AS (SELECT * FROM t1 INNER JOIN t2 ON (t1.id = t2.id))
SELECT * FROM t12

这将失败:

The column 'id' was specified multiple times for 't12'.

现在这是一个大型查询,因为 t1t2 有很多 (+200) 列。我不会全部列出来:我明确地想使用*

通常我会用USING (id) 子句解决这个问题,但SQL Server 似乎不支持。有什么想法吗?

另一种选择是在没有WITH 子句的情况下工作——这工作但会降低代码的可读性。

关于 SO 有很多答案可以让您列出所有字段。在 WITH 子句和纯 SQL 中,这是一个明确的问题。诸如“排除字段”herehere 以及一个for views 之类的相关问题要求非ANSI SQL 功能。这个问题是针对纯 SQL 的,如果 SQL Server 支持 ANSI SQL-92 语法,则可能(据我所知)。

【问题讨论】:

  • "这是一个明确的问题。" - 你不能
  • @MartinSmith,好的,谢谢。在事情发生变化之前,我不会回答它。
  • 是否可以选择动态创建 SQL(直接在 T-SQL 中或在您选择的客户端语言中)?
  • @Heinzi,谢谢,但没有。这是一个明确的 SQL 问题。
  • @DavorJosipovic:好的。然后我认为你别无选择,但我很高兴被证明是错误的。

标签: sql sql-server


【解决方案1】:

您不能使用包含 2 个或更多具有完全相同名称的列的子查询(CTE 或常规子查询)。不幸的是,没有解决方法。您唯一的选择是在选择重复列时显式更改它们的别名,无论是手动还是通过动态 SQL。

【讨论】:

    【解决方案2】:

    问题不在ON 子句中。它位于SELECT。使用* 会同时选择t1.idt2.id。这两个具有相同的名称,因此您得到的错误。

    我能看到的唯一解决方法是将* 应用于列数最多的表,并明确命名您要选择的另一个表的列:

    WITH t12 AS (
       SELECT t1.*, t2.myColumn, etc...  
       FROM t1 
       INNER JOIN t2 ON (t1.id = t2.id)
    )
    SELECT * FROM t12
    

    【讨论】:

    • 然后使用脚本列出第二个表的列,这样就不用输入了
    • 如果t1 有一个名为myColumn 的列,那么它仍然会失败(列不同但问题相同)。
    • @EzequielLópezPetrucci 这应该不是问题,因为另一个表的列是明确指定的。我已经解释了名称冲突的问题所在,因此很清楚应该省略所有具有相同名称的列。
    • @GiorgosBetsos 但是有人可能会提到,如果您需要从第二个表中选择具有相同名称的列,您可以为它们设置别名。特别是如果使用彼得史密斯的建议。虽然这对大多数人来说非常明显,但我猜。