TSQL -如何避免UNION ALL



样本数据:

DECLARE @Parent TABLE
(
[Id] INT
, [Misc_Val] VARCHAR(5)
) ;
DECLARE @Children TABLE
(
[Id]   INT
, [P_ID] INT
) ;
INSERT INTO @Parent
VALUES
( 1, 'One' )
, ( 2, 'Two' )
, ( 3, 'Three' )
, ( 5, 'Four' ) ;
INSERT INTO @Children
VALUES
( 10, 1 )
, ( 11, 1 )
, ( 21, 2 )
, ( 23, 2 )
, ( 30, 3 )
, ( 40, 4 ) ;

目标:有效输出三个字段([Id]和[IsChild], [Misc_Val])。输出@Parent表中[IsChild] = 0的所有记录,并输出@Child表中(@Parent)的所有匹配记录。Id = @Children.P_Id) with [IsChild] = 1.

预期输出

Id  IsChild Misc_Val
1   0       One
2   0       Two
3   0       Three
5   0       Four
10  1       One
11  1       One
21  1       Two
23  1       Two
30  1       Three

我的尝试:

SELECT  [P].[Id]
, 0 AS [IsChild]
, [P].[Misc_Val]
FROM    @Parent AS [P]
UNION ALL
SELECT  [C].[Id]
, 1
, [P].[Misc_Val]
FROM    @Parent AS [P]
JOIN    @Children AS [C]
ON      [C].[P_ID] = [P].[Id] ;

是否有比使用UNION ALL更好的方法?@Parent和@Children表非常大,所以我尽量避免查询@Parent表两次。

更新:下面的答案让我意识到我在创建带有模拟数据的帖子时遗漏了一些东西。无论在最终输出中,我们都需要@Parent表中的一些额外数据。

您可以使用CROSS APPLY将子表添加到父表。

这可能会更快,也可能不会更快,这取决于索引等等。您需要检查执行计划。

SELECT  v.Id
, v.IsChild
, P.Misc_Val
FROM    @Parent AS P
CROSS APPLY (
SELECT
P.Id,
0 AS IsChild
UNION ALL
SELECT
C.Id,
1
FROM @Children AS C
WHERE C.P_ID = P.Id
) v;

请注意,应用程序中的第一个SELECT没有FROM,因此没有进行任何表访问。

相关内容

  • 没有找到相关文章

最新更新