Sql 在主查询中使用子查询结果

Sql 在主查询中使用子查询结果,sql,sql-server,subquery,Sql,Sql Server,Subquery,如何使子查询结果在主查询中可用,如本例所示 SELECT Id AS ParticipantId, TeamId, ISNULL((SELECT TOP(1) Weight FROM ParticipantData WHERE (ParticipantId = Participants.Id) AND (Weight <> 0) ORDER BY Date), 0) AS FirstWeight, ISNULL((SELECT TOP(1) Weight FROM Participa

如何使子查询结果在主查询中可用,如本例所示

SELECT Id AS ParticipantId, TeamId,
ISNULL((SELECT TOP(1) Weight FROM ParticipantData WHERE (ParticipantId = Participants.Id) AND (Weight <> 0) ORDER BY Date), 0) AS FirstWeight,
ISNULL((SELECT TOP(1) Weight FROM ParticipantData WHERE (ParticipantId = Participants.Id) AND (Weight <> 0) ORDER BY Date DESC), 0) AS LastWeight,
FirstWeight - LastWeight As WeightDiff // this doesn't work
FROM Participants

一种方法是将当前查询放入CTE,然后使用别名对其进行子查询:

WITH cte AS (
    SELECT Id AS ParticipantId, TeamId,
        ISNULL((SELECT TOP(1) Weight FROM ParticipantData WHERE (ParticipantId = Participants.Id) AND (Weight <> 0) ORDER BY Date), 0) AS FirstWeight,
        ISNULL((SELECT TOP(1) Weight FROM ParticipantData WHERE (ParticipantId = Participants.Id) AND (Weight <> 0) ORDER BY Date DESC), 0) AS LastWeight
    FROM Participants
)

SELECT
    ParticipantId,
    TeamId,
    FirstWeight,
    LastWeight,
    FirstWeight - LastWeight As WeightDiff
FROM cte;

FirstWeight,lastwweight行内别名将不起作用sql server您可以通过以下方式更改查询

SELECT Id AS ParticipantId, TeamId,
ISNULL((SELECT TOP(1) Weight FROM ParticipantData WHERE (ParticipantId = Participants.Id) AND (Weight <> 0) ORDER BY Date), 0) AS FirstWeight,
ISNULL((SELECT TOP(1) Weight FROM ParticipantData WHERE (ParticipantId = Participants.Id) AND (Weight <> 0) ORDER BY Date DESC), 0) AS LastWeight,
ISNULL((SELECT TOP(1) Weight FROM ParticipantData WHERE (ParticipantId = Participants.Id) AND (Weight <> 0) ORDER BY Date), 0)- ISNULL((SELECT TOP(1) Weight FROM ParticipantData WHERE (ParticipantId = Participants.Id) AND (Weight <> 0) ORDER BY Date DESC), 0) As WeightDiff // this doesn't work
FROM Participants
也可以使用子查询进行下一级查询

select ParticipantId, TeamId,FirstWeight,LastWeight,
 FirstWeight-LastWeight as WeightDiff from
  ( 
  SELECT Id AS ParticipantId, TeamId,
    ISNULL((SELECT TOP(1) Weight FROM ParticipantData WHERE (ParticipantId = Participants.Id) AND (Weight <> 0) ORDER BY Date), 0) AS FirstWeight,
    ISNULL((SELECT TOP(1) Weight FROM ParticipantData WHERE (ParticipantId = Participants.Id) AND (Weight <> 0) ORDER BY Date DESC), 0) AS LastWeight
FROM Participants
  ) as t
使用外部应用程序:


谢谢我知道我可以再次进行子查询来进行计算,但我认为有更好的方法。还要考虑性能。@Mads cte或子查询必须直接,但在alias中无效。您能帮我完成您的第二个示例吗?@Mads我编辑过,这只是您的查询,在顶级查询库中有所不同,很好。由于性能原因,我给你正确的答案。看起来不错。它的性能比多子查询好吗?不,多子查询版本可能会性能更好。但是,它看起来更糟糕,从编码的角度来看,可能更难维护。由您决定要使用哪个版本。@Mads我花了大约15分钟试图使用常规联接重写您的查询,但无法做到。假设您需要这个精确的输出,您可能必须坚持当前的方法。您是对的,它看起来比所有子查询都简单,但在这种情况下,我必须考虑性能。谢谢,Gordon!与子查询/联接相比,交叉应用在性能方面如何?@Mads。它应该相当于子查询。您必须进行测试,以查看在任何特定情况下它与联接的比较情况。
SELECT Id AS ParticipantId, TeamId,
       COALESCE(f.FirstWeight, 0) as FirstWeight,
       COALESCE(f.LastWeight, 0) as LastWeight,
       (f.FirstWeight - l.LastWeight) As WeightDiff 
FROM Participants p OUTER APPLY
     (SELECT TOP(1) pd.Weight as firstWeight
      FROM ParticipantData pd
      WHERE (pd.ParticipantId = p.Id) AND Weight <> 0
      ORDER BY Date
     ) f OUTER APPLY
     (SELECT TOP(1) pd.Weight as lastWeight
      FROM ParticipantData pd
      WHERE (pd.ParticipantId = p.Id) AND Weight <> 0
      ORDER BY Date DESC
     ) l;