您好我想创建一个VIEW,里面有CTE,这是我的原始查询(简化):
SELECT ISNULL(( SELECT col_a
FROM Table_A a
WHERE a.id = b.id
), 'N/A') ,
b.*
FROM Table_B b
如果我想将其转换为带有CTE的VIEW,我收到错误The multi-part identifier "b.id" could not be bound.
这是我试过的
CREATE VIEW my_view
AS
WITH my_CTE
AS ( SELECT ISNULL(( SELECT col_a
FROM Table_A a
WHERE a.id = b.id
), 'N/A') my_col
)
SELECT ( SELECT *
FROM my_CTE
) CTE_col ,
b.*
FROM Table_B b
请注意,要求是让ISNULL进入CTE,但这意味着a.id是CTE内部的内联查询,这意味着我无法在视图的SELECT中执行WHERE子句。
答案 0 :(得分:1)
这是查询:
WITH my_CTE AS (
SELECT ISNULL((SELECT col_a
FROM Table_A a
WHERE a.id = b.id
), 'N/A'
) my_col
)
SELECT (SELECT * FROM my_CTE) CTE_col, b.*
FROM Table_B b;
CTE在子查询中引用b
。它没有在那时定义。您无法在CTE中拆分相关子查询。
您可以使用cross apply
:
SELECT my_CTE.my_col CTE_col, b.*
FROM Table_B b CROSS APPLY
(SELECT ISNULL((SELECT col_a
FROM Table_A a
WHERE a.id = b.id
), 'N/A'
) my_col
) my_CTE
还有其他方法可以简化您的特定查询,但这可能会解决您的大问题。
答案 1 :(得分:1)
我会删除CTE中的WHERE
子句,然后加入CTE和Table_B
。它应该是这样的:
CREATE VIEW my_view
AS
WITH my_CTE
AS ( SELECT my_col = ISNULL(col_a, 'N/A') ,
a.id
FROM Table_A a
)
SELECT CTE_col = my_CTE.my_col ,
b.*
FROM Table_B b
JOIN my_CTE ON b.id = my_CTE.id
编辑:
到目前为止,我从未与FOR XML PATH
合作过,所以我不确定这是否是你想要的。
这是一个用于连接两个表的CTE和一个仅用于XML的CTE。
也许JOIN
需要LEFT JOIN
,但这取决于您的数据
如果Table_A
始终具有相应的ID且col_a
可以为空,则INNER JOIN
就足够了。
如果您想在N/A
中为不存在的记录显示Table_A
,则需要LEFT JOIN
。
CREATE VIEW my_view
AS
WITH my_CTE
AS ( SELECT my_col = ISNULL(a.col_a, 'N/A') ,
b.*
FROM Table_A a
INNER JOIN Table_B b ON a.id = b.id
),
xml_cte
AS ( SELECT my_col
FROM my_CTE
FOR XML PATH
)
SELECT *
FROM my_CTE
答案 2 :(得分:1)
替代: (下面的代码已经完成了。发布的问题类似于https://meta.stackexchange.com/q/185681的评论中的讨论。我实际上无法在不留下文本中的SO链接的情况下发布答案。我道歉。)
WITH my_CTE(b_id, col_A) AS
(
SELECT b.id, ISNULL(a.col_a, 'N/A')
FROM Table_B b
LEFT OUTER JOIN Table_A a ON b.id = a.id
)
SELECT my_CTE.col_A, b.*
FROM Table_B b
INNER JOIN my_CTE ON b.id = my_CTE.b_id