SQL - 临时表并选择行而不是集合

时间:2014-07-21 19:44:29

标签: sql sql-server aggregate-functions temp-tables

我还在正确地学习SQL并且遇到了一个我知道可以解决的问题我只是不确定如何。

我现在的查询 -

  SELECT 
  'E3FBE4EC-B5AA-4558-A9A1-003D05D9A92E' AS TeamId,
  Div AS CompetitionId,
  Count(*) AS GamesPlayed,
  Sum(HomeGoals) AS HomeGoals,
  Sum(AwayGoals) AS HomeGoalsConceded,
  Sum(HalfTimeHomeGoals) AS HalfTimeHomeGoals,
  Sum(HalfTimeAwayGoals) AS HalfTimeHomeGoalsConceded,
  Sum(HomeTeamCorners) AS HomeCorners,
  Sum(AwayTeamCorners) AS HomeCornersConceded,
  Sum(HomeTeamFouls) AS HomeFouls,
  Sum(HomeTeamYellows) AS HomeYellows,
  Sum(HomeTeamReds) AS HomeReds
  FROM
  (
      SELECT TOP 10 *
      FROM dbo.Match
      INNER JOIN dbo.MatchDetail ON dbo.Match.Id = dbo.MatchDetail.MatchId
      WHERE (HomeTeamId = 'E3FBE4EC-B5AA-4558-A9A1-003D05D9A92E'
        OR AwayTeamId = 'E3FBE4EC-B5AA-4558-A9A1-003D05D9A92E')
      ORDER BY [Date] DESC
  ) AS LatestMatches
 WHERE HomeTeamId = 'E3FBE4EC-B5AA-4558-A9A1-003D05D9A92E'
 GROUP BY Div
  SELECT 
  'E3FBE4EC-B5AA-4558-A9A1-003D05D9A92E' AS TeamId,
  Div AS CompetitionId,
  Count(*) AS GamesPlayed,
  Sum(AwayGoals) AS AwayGoals,
  Sum(HomeGoals) AS AwayGoalsConceded,
  Sum(HalfTimeAwayGoals) AS HalfTimeAwayGoals,
  Sum(HalfTimeHomeGoals) AS HalfTimeAwayGoalsConceded,
  Sum(AwayTeamCorners) AS AwayCorners,
  Sum(HomeTeamCorners) AS AwayCornersConceded,
  Sum(AwayTeamFouls) AS AwayFouls,
  Sum(AwayTeamYellows) AS AwayYellows,
  Sum(AwayTeamReds) AS AwayReds
  FROM
  (
      SELECT TOP 10 *
      FROM dbo.Match
      INNER JOIN dbo.MatchDetail ON dbo.Match.Id = dbo.MatchDetail.MatchId
      WHERE (HomeTeamId = 'E3FBE4EC-B5AA-4558-A9A1-003D05D9A92E'
        OR AwayTeamId = 'E3FBE4EC-B5AA-4558-A9A1-003D05D9A92E')
      ORDER BY [Date] DESC
  ) AS LatestMatches
 WHERE AwayTeamId = 'E3FBE4EC-B5AA-4558-A9A1-003D05D9A92E'
 GROUP BY Div

我明白这是非常凌乱的,首先我可以将“SELECT TOP 10 *”删除到临时表中,如何?其次要进一步改进它,我可以用一行而不是两行/集来实现这个吗?

如果需要,请提前致谢解释。

2 个答案:

答案 0 :(得分:1)

将其添加到SQL的开头:

SELECT TOP 10 *
  INTO #TopMatches
  FROM dbo.Match
  INNER JOIN dbo.MatchDetail ON dbo.Match.Id = dbo.MatchDetail.MatchId
  WHERE (HomeTeamId = 'E3FBE4EC-B5AA-4558-A9A1-003D05D9A92E'
    OR AwayTeamId = 'E3FBE4EC-B5AA-4558-A9A1-003D05D9A92E')
  ORDER BY [Date] DESC

然后使用这个临时表,所以这个:

FROM
(
  SELECT TOP 10 *
  FROM dbo.Match
  INNER JOIN dbo.MatchDetail ON dbo.Match.Id = dbo.MatchDetail.MatchId
  WHERE (HomeTeamId = 'E3FBE4EC-B5AA-4558-A9A1-003D05D9A92E'
    OR AwayTeamId = 'E3FBE4EC-B5AA-4558-A9A1-003D05D9A92E')
  ORDER BY [Date] DESC
) AS LatestMatches

成为这个:

FROM #TopMatches AS LatestMatches

或者,我实际上会使用TABLE变量,但这需要知道结构(你应该在你的问题中发布)

理想情况下,这就是你真正想要的:

 DECLARE @TopMatches TABLE( COL1 AS INT, COL2 AS VARCHAR)   <-- fully define what columns you need to store

现在使用查询

填充它
 INSERT @TopMatches(COL1, COL2 .... ) SELECT TOP 10 *
  INTO #TopMatches
  FROM dbo.Match
  INNER JOIN dbo.MatchDetail ON dbo.Match.Id = dbo.MatchDetail.MatchId
  WHERE (HomeTeamId = 'E3FBE4EC-B5AA-4558-A9A1-003D05D9A92E'
    OR AwayTeamId = 'E3FBE4EC-B5AA-4558-A9A1-003D05D9A92E')
  ORDER BY [Date] DESC

如果您想要一个单一的结果集,我建议您将列更改为更通用,例如,您有AwayGoalsHomeGoals,而应添加名为Team的列,给它一个HomeAway的值然后你可以做一个UNION并获得一个结果:

您可以做的一个小例子:

SELECT 'Home' AS [Team],
'E3FBE4EC-B5AA-4558-A9A1-003D05D9A92E' AS TeamId,
 Div AS CompetitionId,
 Count(*) AS GamesPlayed,
 Sum(AwayGoals) AS Goals
FROM #TopMatches AS LatestMatches
WHERE ....   <-- whatever criteria for HOME
UNION ALL
SELECT 'Away' AS [Team],
'E3FBE4EC-B5AA-4558-A9A1-003D05D9A92E' AS TeamId,
 Div AS CompetitionId,
 Count(*) AS GamesPlayed,
 Sum(AwayGoals) AS Goals
FROM #TopMatches AS LatestMatches
WHERE ....   <-- whatever criteria for AWAY

答案 1 :(得分:1)

这样的东西?

with MatchDetails as
(
    SELECT TOP 10 
    Div as CompetitionID
    , AwayGoals
    , HomeGoals
    , HalfTimeAwayGoals
    , HalfTimeHomeGoals
    , AwayTeamCorners
    , HomeTeamCorners
    , AwayTeamFouls
    , AwayTeamYellows
    , AwayTeamReds
  FROM dbo.Match
  INNER JOIN dbo.MatchDetail ON dbo.Match.Id = dbo.MatchDetail.MatchId
  WHERE (HomeTeamId = 'E3FBE4EC-B5AA-4558-A9A1-003D05D9A92E'
    OR AwayTeamId = 'E3FBE4EC-B5AA-4558-A9A1-003D05D9A92E')
  ORDER BY MatchDate DESC
)

SELECT 
  'E3FBE4EC-B5AA-4558-A9A1-003D05D9A92E' AS TeamId,
  Div AS CompetitionId,
  Count(*) AS GamesPlayed,
  Sum(HomeGoals) AS HomeGoals,
  Sum(AwayGoals) AS HomeGoalsConceded,
  Sum(HalfTimeHomeGoals) AS HalfTimeHomeGoals,
  Sum(HalfTimeAwayGoals) AS HalfTimeHomeGoalsConceded,
  Sum(HomeTeamCorners) AS HomeCorners,
  Sum(AwayTeamCorners) AS HomeCornersConceded,
  Sum(HomeTeamFouls) AS HomeFouls,
  Sum(HomeTeamYellows) AS HomeYellows,
  Sum(HomeTeamReds) AS HomeReds
from MatchDetails
group by CompetitionID

我会提出一些建议。首先,我将您的列命名为MatchDate而不是Date。日期是一个保​​留字,非常含糊不清。如果Date表示CreatedDate或其他日期,该怎么办?

其次,更重要的是我强烈建议你研究规范化。您不需要AwayGoals和HomeGoals的列。如果它是另一个名为Goals的表并包含TeamID,那将会好得多。与Corners,Fouls,Cards(通知卡是规范化的另一个机会)相同,不需要两张牌桌,只需一张牌和一张牌类型以及playerID(或团队,如果不在玩家级别跟踪)就足够了。