嵌套多个相同的选择查询并重复使用,而无需第二次往返数据库

时间:2019-01-07 15:30:01

标签: sql sql-server

我在数据库中有两个不同ID的行。现在,我试图在一行中显示两个不同的数据列,我尝试了如下操作:

SELECT
    [dbo].[fnHexToNumber]([Participant].[Stake]) AS [PlayerStake],
    (SELECT [dbo].[fnHexToNumber]([Stake]) 
     FROM [dbo].[Participant_Complete] 
     WHERE [ParticipantId] = [Fold].[HouseParticipantId]) AS [HouseStake],
    ([dbo].[fnHexToNumber]([Participant].[Stake]) + [dbo].[fnHexToNumber]([C].[RunningWinLoss])) AS [PlayerStakeAfterRound],
    (SELECT [dbo].[fnHexToNumber]([Stake]) 
     FROM [dbo].[Participant_Complete] 
     WHERE [ParticipantId] = [Fold].[HouseParticipantId]) - [dbo].[fnHexToNumber]([C].[RunningWinLoss]) AS [HouseStakeAfterRound]
FROM 
    [dbo].[Round_Complete] AS [C]
INNER JOIN 
    [dbo].[Fold_Complete] AS [Fold] ON [Fold].[Id] = [C].[Id]
INNER JOIN 
    [dbo].[Participant_Complete] AS [Participant] ON [Participant].[ParticipantId] = [Fold].[PlayerParticipantId]

这有效,但是如您所见,它将对同一嵌套选择进行两次数据库访问。我怎样才能使这只有一次往返?

2 个答案:

答案 0 :(得分:1)

您指的是子查询。这不是“往返数据库”,通常是指调用查询的应用程序。

所有方括号使查询难以阅读,但是您可以使用apply来解决此问题:

SELECT [dbo].[fnHexToNumber](p.[Stake]) AS PlayerStake,
       h.HouseStake,
       ([dbo].[fnHexToNumber](p.[Stake]) + [dbo].[fnHexToNumber]([C].RunningWinLoss)) AS PlayerStakeAfterRound,
        (h.HouseStake - [dbo].fnHexToNumber(C.RunningWinLoss)) AS HouseStakeAfterRound
FROM [dbo].[Round_Complete] c JOIN
     [dbo].[Fold_Complete] f
     ON f.[Id] = c.[Id] JOIN
     [dbo].[Participant_Complete] pc
     ON px.[ParticipantId] = f.[PlayerParticipantId] OUTER APPLY
     (SELECT [dbo].[fnHexToNumber]([Stake]) as HouseStake
      FROM [dbo].[Participant_Complete] pch
      WHERE pch.ParticipantId = f.HouseParticipantId
     ) h

答案 1 :(得分:0)

只需第二次连接同一张表,而不是将数据作为子查询拉出。

此外,如果名称中包含空格(通常是不好的做法),则只需要在名称两边加上方括号即可。如果名称中没有空格,则括号完全是多余的。

SELECT
    dbo.fnHexToNumber(Participant.Stake) AS PlayerStake,
    dbo.fnHexToNumber(p.Stake) as HouseStake,
    (dbo.fnHexToNumber(Participant.Stake) + dbo.fnHexToNumber(C.RunningWinLoss)) AS PlayerStakeAfterRound,
    dbo.fnHexToNumber(p.Stake) - dbo.fnHexToNumber(c.RunningWinLoss) as HouseStakeAfterRound
FROM dbo.Round_Complete AS C
INNER JOIN dbo.Fold_Complete AS Fold 
    ON Fold.Id = C.Id
INNER JOIN dbo.Participant_Complete AS Participant 
    ON Participant.ParticipantId = Fold.PlayerParticipantId
INNER JOIN dbo.Participant_Complete AS p 
    ON p.ParticipantId = Fold.HouseParticipantId