1

我正在使用 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-query 的范围内,MAT_WS_ID 只能从 Y_ALIAS 表中获知。(或者我错了,我更像是一个 C++,也许 SQL 和 C++ 中的范围是完全不同的)

我只是想知道在 SQL Server 中重用标量选择结果的最佳方法是什么。或者我应该不关心并复制每一列的选择,而 sql 服务器自己优化它?

4

2 回答 2

2

一种方法是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
于 2012-08-05T17:27:50.400 回答
0

您可以在前者和后者中对行进行排名#TempTableX#TempTableY分区,然后在两个表中使用常规连接和过滤(作为包含两个表中每个表中的排名数字的列):MAT_RM_NAMEMAT_WS_IDrownum = 1rownum

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
;

ORDER BY (SELECT 1)位是指定不确定排序的技巧,因此会导致rownum = 1查询选择不确定的行。那就是在没有明确顺序的情况下或多或少地复制您TOP 1的内容,但我建议您指定一个更明智的ORDER BY子句以使结果更可预测。

于 2012-08-05T20:32:04.663 回答