嵌套选择还是加入?

use*_*175 5 sql sql-server

这是我存储的Proc的片段

SELECT  NULL AS StoryID
      , AlbumID
      , CAST(NULL as varchar) AS StoryTitle
      , AlbumName
      , (SELECT URL FROM AlbumPictures AS AlbumPictures_3 WHERE (AlbumID = Albums.AlbumID) AND (AlbumCover = 'True')) AS AlbumCover
      , Votes
      , CAST(NULL as Int) AS PictureId
      , 'albums' AS tableName
      , (SELECT NestedAlbums.AlbumID FROM NestedAlbums WHERE (AlbumID = Albums.AlbumID)) AS Flag
INTO #Results2
FROM Albums WHERE AlbumID IN (SELECT StringVal FROM funcListToTableInt(@whereAlbumID))
Run Code Online (Sandbox Code Playgroud)

我在上面的查询中使用了嵌套选择.我很好奇,想知道是否Nested Selects有优于LEFT/Right JOINS或者我应该使用JOINS

表相册:

在此输入图像描述

表NestedAlbums:

在此输入图像描述

Mar*_*ith 8

一般来说,写一个明确的OUTER JOIN会更好.

SQL Server可能需要使用子查询版本向计划添加Assert,该子查询版本验证子查询最多只返回一行(除非这由唯一索引保证).这可能会限制可用的可能转换.有关此内容的更多信息,请参见标量子查询.

另外(虽然与您的问题中的示例无关,因为两个子查询都不同)写入显式JOIN允许您使用连接表中的多个列进行一次查找,而使用单独的类似子查询则不会(SQL Server没有逻辑可检测)常见的子表达式).

编辑:

以下是评论中的讨论

SELECT NULL                      AS StoryID,
       A.AlbumID,
       CAST(NULL AS VARCHAR(30)) AS StoryTitle,
       A.AlbumName,
       AP.URL                    AS AlbumCover,
       A.Votes,
       CAST(NULL AS INT)         AS PictureId,
       'albums'                  AS tableName,
       CASE
         WHEN EXISTS (SELECT *
                      FROM   NestedAlbums NA
                      WHERE  NA.AlbumID = A.AlbumID
                             AND ( AccountId = @AccountId )) THEN 1
         ELSE 0
       END                       AS Flag
INTO   #Results2
FROM   Albums A
       LEFT OUTER JOIN AlbumPictures AP
         ON ( AP.AlbumID = A.AlbumID )
            AND ( AP.AlbumCover = 'True' )
WHERE  A.AlbumID IN (SELECT StringVal
                     FROM   funcListToTableInt(@whereAlbumID)) 
Run Code Online (Sandbox Code Playgroud)

您可能会注意到这仍然在SELECT列表中有一个子查询,但CASE ... EXISTS 将作为半连接有效地实现.

目前,您的查询假定每个相册最多会返回一个匹配的行AlbumPictures,如果此假设不成立则会出错.这会改变语义,因为不会返回任何错误,并且您将获得具有各种URLs的多行.如果你不希望这种情况发生,你需要定义URL使用哪个并添加一个GROUP BY