LEFT JOIN with subquery并访问select子句中的主表列

时间:2017-08-08 07:13:33

标签: sql sql-server tsql

我有一个类似下面的插入语句,它会产生"the multi-part identifier "t2.Col1" could not be bound."的sytax错误。我简化了语句,它看起来如下:

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将值与分隔符连接起来,然后我解析该连接字符串并将适当的值放在其中。

2 个答案:

答案 0 :(得分:2)

您可以使用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 APPLYCROSS APPLY on this thread

3号,"重用表别名"与您的案例类似,与之相关的文章完美地解释了如何在这些案例中使用cross apply/outer apply

答案 1 :(得分:0)

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

但在这种情况下你真的不需要JOIN或OUTER APPLY。

只需在子查询中使用CASE从T2中选择

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。这可能比写出数百个条件更快。但话说回来,你确实说过这很简单了。