使用子查询的LEFT JOIN,以及在SELECT子句中访问主表列

3

我有一个插入语句,像下面这样,会出现语法错误"the multi-part identifier "t2.Col1" could not be bound."。我简化了语句,它看起来像下面这样:

INSERT INTO dbo.T1
(
    Col1,
    Col2,
    Col3
)
SELECT 
    t2.Col1,
    SUBSTRING(aCase.CaseColumn, 0, CHARINDEX('%', aCase.CaseColumn)), --I expect this line gets the value "2"
    SUBSTRING(aCase.CaseColumn, CHARINDEX('%', aCase.CaseColumn) + 1, LEN(aCase.CaseColumn) - CHARINDEX('%', aCase.CaseColumn)) --I expect this line gets the value "3"
FROM 
    dbo.T2 t2
LEFT JOIN 
(
    SELECT 
        CASE --I have hundreds of WHEN conditions below and need to access the parent T2 tables' properties
            WHEN t2.Col1 = 1 THEN '2%3' --This line has a syntax error of "the multi-part identifier "t2.Col1" could not be bound."
        END AS CaseColumn
) 
AS aCase ON 1 = 1 

我使用 LEFT JOINCASE 的原因是我有数百个条件需要选择不同的列值。我不想为所有列重复相同的 CASE 语句。因此,我使用一个单独的 CASE 将值与分隔符连接起来,然后解析该连接字符串并将适当的值放在其位置。


为什么不将整个表查询移入连接中,然后从中选择?由于您在主查询中根本没有使用T2,因此它不需要出现在那里,并且简化了事情。 - Sami Kuhmonen
它实际上已经被使用了,但我没有把它放在那里,以使它看起来更简单。请检查我的编辑。 - yakya
好的,那么您可以从连接的选择中选择这些列,并从那里使用它们,因为它们似乎是一一对应的。似乎已经有人建议这作为答案。 - Sami Kuhmonen
2个回答

3
您可以使用OUTER APPLY,因为它允许您将dbo.T2aCase结果集相关联,代码如下:
INSERT INTO dbo.T1
(
    Col1,
    Col2,
    Col3
)
SELECT 
    1,
    SUBSTRING(aCase.CaseColumn, 0, CHARINDEX('%', aCase.CaseColumn)), --I expect this line gets the value "2"
    SUBSTRING(aCase.CaseColumn, CHARINDEX('%', aCase.CaseColumn) + 1, LEN(aCase.CaseColumn) - CHARINDEX('%', aCase.CaseColumn)) --I expect this line gets the value "3"
FROM 
    dbo.T2 t2
OUTER APPLY
(
    SELECT 
        CASE --I have hundreds of WHEN conditions below and need to access the parent T2 tables' properties
            WHEN t2.Col1 = 1 THEN '2%3' 
        END AS CaseColumn
) 
AS aCase ON 1 = 1 

由于子查询的结果本身不独立,需要根据dbo.T2表的值进行定义。
此线程中了解更多关于OUTER APPLY和CROSS APPLY的信息。
第三点“重复使用表别名”与您的情况相似,链接的文章完美地解释了如何在这些情况下使用cross apply/outer apply。

0

当使用连接到子查询时,在该子查询内部它不知道t2是什么,除非你在该子查询中选择一个别名为t2的表。
并且你可以将LEFT JOIN更改为OUTER APPLY。

但在这种情况下,你实际上不需要JOIN或OUTER APPLY。

只需在子查询中选择T2和CASE即可。

INSERT INTO dbo.T1
(
    Col1,
    Col2,
    Col3
)
SELECT 
    Col1,
    SUBSTRING(CaseColumn, 1, CHARINDEX('%', CaseColumn)-1),
    SUBSTRING(CaseColumn, CHARINDEX('%',CaseColumn)+1, LEN(CaseColumn))
FROM 
(
  SELECT 
   Col1,
   CASE Col1
    WHEN 1 THEN '2%3'
    -- more when's
   END AS CaseColumn
  FROM dbo.T2 t2
) q

注意CASE和SUBSTRING的一些变化。

顺便说一下,个人认为最好将不同的Col1插入到T1中,并手动更新该参考表中的Col2和Col3。这可能比编写那些数百个条件更快。但是再次强调,您确实说这简化了很多。


你错过了我的最后一次编辑。我编辑了选择1到t2.Col1的部分。 - yakya
@sotn 确实,我错过了那个。而且我一直想知道为什么要插入一个固定的数字。固定的。 - LukStorms

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接