IGNORE“列被多次指定为”CTE

时间:2018-05-21 01:00:27

标签: sql sql-server common-table-expression

使用以下CTE:

WITH cteRoute AS (
    SELECT *
      FROM CRROUTE cr 
      JOIN crewleg cl on (cr.CDATE = cl.CDATE AND cr.CROUTE = cl.croute)
      left JOIN legmain lm on (lm.DAY = cl.DAY AND lm.DEP = cl.DEP and lm.CARRIER = cl.CARRIER and lm.FLT = cl.FLT and lm.LEGCD = cl.LEGCD )
      left JOIN legtimes lt on (lt.DAY = lm.DAY AND lt.DEP = lm.DEP and lt.CARRIER = lm.CARRIER and lt.FLT = lm.FLT and lt.LEGCD = lm.LEGCD )
      where cr.cdate = 14000
      and cr.croute = 138266498116
)

我收到一条错误,说明在CTE中多次选择了CARRIER。

是的,这是正确的。由于SELECT *确实已多次选择它。

我的问题是如何解决这个问题。我知道如何通过专门枚举查询中的特定列而不是通过SELECT *.

选择所有列来解决这个问题。

问题在于我正在使用的数据库是来自第三方供应商(在希腊),我无法控制,他们在数据库设计和规范化方面非常“笨拙”。

此查询将返回几个HUNDRED列。我真的不想具体枚举它们。

SQL Server查询引擎非常能够提取多个同名的列:

SELECT 'this' as LABEL, 'that' as LABEL

工作得很好,返回两个名为“LABEL”的列。

我的问题是,是否有办法告诉查询引擎忽略公用表表达式中的重复列名?

它能够在正常查询中执行此操作(如上所示),但似乎无法在CTE中执行此操作。

有问题的列是JOIN链接中使用的列,它们将始终相等。

更新

此问题与其他问题相似,但唯一的细微差别使其不重复。如果这个实际上 IS 是重复的,那么请务必将其标记为这样,我会非常高兴 - 特别是如果它有答案的话。

1 个答案:

答案 0 :(得分:3)

这是减少必须手动输入内容的一种方法。

运行以下代码

  SELECT 
    CASE 
      WHEN t.name = 'crewleg' THEN 'cl.' + c.name + ','
      WHEN t.name = 'legmain' THEN 'lm.' + c.name + ','
      WHEN t.name = 'legtimes' THEN 'lt.' + c.name + ','
    END
  FROM sys.tables t
  join sys.columns c on c.object_id = t.object_id
  WHERE t.name in ('crewleg', 'legmain', 'legtimes')

这将返回alias.前面的每个列以及列名后面的逗号。将其复制到记事本。此时,您可以直接找到导致问题的列,并为它们提供别名,这样它们就不会重复。你也可以使用notepad ++来查找和替换所有回车符,这样select就不会垂直。不要忘记删除最后一个逗号,因为它将是额外的。然后将其复制并粘贴回您的选择中。