Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在插入的WHERE子句中重用子查询结果_Sql_Sql Server - Fatal编程技术网

Sql 在插入的WHERE子句中重用子查询结果

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

我正在使用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 = 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
子句,以使结果更可预测。

您应该始终连接到一个表上并删除内部选择以获得更好的性能,如果有多个类似语句?这取决于相似性的类型。一个选项是mulitple
outer 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
;