在select子句中使用子查询和访问主表列的LEFT JOIN

13 浏览
0 Comments

在select子句中使用子查询和访问主表列的LEFT JOIN

我有一个像下面这样的插入语句,出现了语法错误"无法绑定多部分标识符“t2.Col1”"。我过于简化了语句,看起来如下所示:

INSERT INTO dbo.T1
(
    Col1,
    Col2,
    Col3
)
SELECT 
    t2.Col1,
    SUBSTRING(aCase.CaseColumn, 0, CHARINDEX('%', aCase.CaseColumn)), --我期望这一行得到值"2"
    SUBSTRING(aCase.CaseColumn, CHARINDEX('%', aCase.CaseColumn) + 1, LEN(aCase.CaseColumn) - CHARINDEX('%', aCase.CaseColumn)) --我期望这一行得到值"3"
FROM 
    dbo.T2 t2
LEFT JOIN 
(
    SELECT 
        CASE --我有数百个以下的WHEN条件,并且需要访问父T2表的属性
            WHEN t2.Col1 = 1 THEN '2%3' --这一行出现语法错误"无法绑定多部分标识符“t2.Col1”"
        END AS CaseColumn
) 
AS aCase ON 1 = 1 

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

0
0 Comments

当在子查询中使用连接(join)时,在子查询中无法识别t2,除非在子查询中使用别名t2来选择表。

你可以将LEFT JOIN更改为OUTER APPLY。

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

只需在子查询中从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。这可能比编写那些数百个条件更快。但再说一次,你确实说这个问题被大大简化了。

你错过了我的最后一次编辑。我编辑了选择1到->t2.Col1的部分。

确实,我漏掉了那个。我想知道为什么会插入一个固定的数字。已修正。

0
0 Comments

LEFT JOIN的子查询和在SELECT子句中访问主表列的问题通常是由于子查询结果与主表的值相关联而引起的。解决这个问题的方法是使用OUTER APPLY,因为它允许dbo.T2和aCase结果集相关联。下面是一个示例代码:

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可以解决这个问题。在下面的链接中可以了解更多关于OUTER APPLY和CROSS APPLY的内容:

[https://stackoverflow.com/questions/9275132](https://stackoverflow.com/questions/9275132)

第3点“重用表别名”与您的情况类似,链接的文章完美地解释了如何在这些情况下使用cross apply/outer apply。

0