Sql 在插入的WHERE子句中重用子查询结果
我正在使用Microsoft SQL Server 2008 我想保存子查询的结果,以便在下面的子查询中重用它。 这可能吗? 这样做的最佳实践是什么?(我对SQL非常陌生) 我的查询如下所示:Sql 在插入的WHERE子句中重用子查询结果,sql,sql-server,Sql,Sql Server,我正在使用Microsoft SQL Server 2008 我想保存子查询的结果,以便在下面的子查询中重用它。 这可能吗? 这样做的最佳实践是什么?(我对SQL非常陌生) 我的查询如下所示: INSERT INTO [dbo].[TestTable] ( [a] ,[b] ) SELECT ( SELECT TOP 1 MAT_WS_ID FROM #TempTableX AS X_ALIAS WHERE OUTERBASETABLE.LT_ALL_MATERIAL
INSERT INTO [dbo].[TestTable]
(
[a]
,[b]
)
SELECT
(
SELECT TOP 1 MAT_WS_ID
FROM #TempTableX AS X_ALIAS
WHERE OUTERBASETABLE.LT_ALL_MATERIAL = X_ALIAS.MAT_RM_NAME
)
,(
SELECT TOP 1 MAT_WS_NAME
FROM #TempTableY AS Y_ALIAS
WHERE Y_ALIAS.MAT_WS_ID = MAT_WS_ID
--(
--SELECT TOP 1 MAT_WS_ID
--FROM #TempTableX AS X_ALIAS
--WHERE OUTERBASETABLE.LT_ALL_MATERIAL = X_ALIAS.MAT_RM_NAME
--)
)
FROM [dbo].[LASERTECHNO] AS OUTERBASETABLE
我的问题是:
我做的对吗。
我用[a](=MAT_WS_ID)的第一个SELECT语句的结果替换了[b]的WHERE子句中的第二个SELECT语句(被注释掉,与[a]完全相同)。
它似乎给出了正确的结果。
但是我不明白为什么
我的意思是MAT_WS_ID是临时表X_ALIAS和Y_ALIAS的一部分。
因此,在[b]的SELECT语句中,在[b]-SELECT查询的范围内,MAT_WS_ID只能从Y_ALIAS表中得知。(或者我错了,我更像是C++,也许SQL和C++中的范围是完全不同的)
我只是想知道SQL Server中重用标量选择结果的最佳方法是什么。
或者,我是否应该不关心并复制select for every column,而sql server会自己对其进行优化?一种方法是
outer apply
:
SELECT mat.MAT_WS_ID
, (
SELECT TOP 1 MAT_WS_NAME
FROM #TempTableY AS Y_ALIAS
WHERE Y_ALIAS.MAT_WS_ID = mat.MAT_WS_ID
)
FROM [dbo].[LASERTECHNO] AS OUTERBASETABLE
OUTER APPLY
(
SELECT TOP 1 MAT_WS_ID
FROM #TempTableX AS X_ALIAS
WHERE OUTERBASETABLE.LT_ALL_MATERIAL = X_ALIAS.MAT_RM_NAME
) as mat
您可以对
#tentrablex
和#tentrabley
中的行进行排序,在前者中通过MAT#RM_NAME
对行进行分区,在后者中通过MAT#WS_ID
对行进行分区,然后在这两个表中使用正常联接并通过rownum=1
进行过滤(rownum
是包含两个表中每个表的排名号的列):
orderby(选择1)
bit是一种指定不确定顺序的技巧,相应地,它将导致查询选择的不确定rownum=1
行。也就是说,在没有明确顺序的情况下或多或少复制您的TOP 1
,但我建议您指定一个更合理的order by
子句,以使结果更可预测。您应该始终连接到一个表上并删除内部选择以获得更好的性能,如果有多个类似语句?这取决于相似性的类型。一个选项是mulitpleouter apply
,但还有其他选项,如
WITH x_ranked AS (
SELECT
*,
rownum = ROW_NUMBER() OVER (PARTITION BY MAT_RM_NAME ORDER BY (SELECT 1))
FROM #TempTableX
),
y_ranked AS (
SELECT
*,
rownum = ROW_NUMBER() OVER (PARTITION BY MAT_WS_ID ORDER BY (SELECT 1))
FROM #TempTableY
)
INSERT INTO dbo.TestTable (a, b)
SELECT
x.MAT_WS_ID,
y.MAT_WS_NAME
FROM dbo.LASERTECHNO t
LEFT JOIN x_ranked x ON t.LT_ALL_MATERIAL = x.MAT_RM_NAME AND x.rownum = 1
LEFT JOIN y_ranked y ON x.MAT_WS_ID = y.MAT_WS_ID AND y.rownum = 1
;