尝试将整体平均值添加到此SQL查询中。

时间:2016-06-10 16:57:44

标签: sql subquery

我有两个有效的查询,并且仍然试图更好地理解子查询,但现在就打了一个墙。

第一个代码工作正常,并做我想要的。我只能得到1-4次下场的比赛,我可以得到AVG(多哥)的平均码数。

Select OffenseTeam, Avg(Togo) as YdsToGo,Down as Downtogo, Down = Case 
when Down =1 Then Count(Down)
when Down =2 Then Count(Down)
when Down =3 Then Count(Down)
when Down =4 Then Count(Down) End 
 From temp_NFL2015
 WHere ToGo <> 0
 Group By OffenseTeam, Down
 Order By OffenseTeam ASC, Downtogo ASC

下一个查询给出了整个联盟的总体平均值,这条查询的结果是四条干净的线条。

Select Down, Avg(Togo) as YTG
 From Temp_NFL2015
 Where Togo<>0
 Group By Down
 Order By Down ASC

现在,当我尝试将它们结合起来时,我失败了。我跟随书籍示例,这似乎是使用的确切格式,但它失败了

Select OffenseTeam, Avg(Togo) as YTG,Down as Downtogo, Down = Case 
when Down =1 Then Count(Down)
when Down =2 Then Count(Down)
when Down =3 Then Count(Down)
when Down =4 Then Count(Down) End 
      (Select Down, Avg(Togo) as YTG
      From Temp_NFL2015
      Where Togo<>0
      Group By Down
      Order By Down ASC) as LGAvg
 From temp_NFL2015
 WHere ToGo <> 0
 Group By OffenseTeam, Down
 Order By OffenseTeam ASC, Downtogo ASC

2 个答案:

答案 0 :(得分:2)

现在,您在子查询中选择了两列并尝试将它们放入一列(Down, Avg(Togo) - &gt; LGAvg

虽然我想建议一个JOIN,但您在这里有两个选项仍然会让您使用子查询,因为您正在学习它们。

一,你可以使用临时表并加入:

 Select   Down, Avg(Togo) as YTG
 Into     #Temp
 From     Temp_NFL2015
 Where    Togo<>0
 Group By Down

然后是主查询:

Select OffenseTeam, Avg(Togo) as YTG,Down as Downtogo, Down = Case 
when Down =1 Then Count(Down)
when Down =2 Then Count(Down)
when Down =3 Then Count(Down)
when Down =4 Then Count(Down) End,
      (Select YTG
      From #TEMP t
      Where t.down = nfl.down) as LGAvg
 From temp_NFL2015 nfl
 Where ToGo <> 0
 Group By OffenseTeam, Down
 Order By OffenseTeam ASC, Downtogo ASC

二,您可以在子查询中使用嵌套选择:

(SELECT YTG 
 FROM (Select Down, Avg(Togo) as YTG
       From Temp_NFL2015
       Where Togo<>0
       Group By Down) avg 
 WHERE avg.Down = nfl.Down) as LGAvg

整个查询:

 Select OffenseTeam, Avg(Togo) as YTG,Down as Downtogo, Down = Case 
    when Down =1 Then Count(Down)
    when Down =2 Then Count(Down)
    when Down =3 Then Count(Down)
    when Down =4 Then Count(Down) End,
   (SELECT YTG 
    FROM (Select Down, Avg(Togo) as YTG
          From Temp_NFL2015
          Where Togo<>0
          Group By Down) avg 
    WHERE avg.Down = nfl.Down) as LGAvg
 From temp_NFL2015 nfl
 Where ToGo <> 0
 Group By OffenseTeam, Down
 Order By OffenseTeam ASC, Downtogo ASC

然后有选项3,即将选项2中的嵌套选择逻辑放入JOIN,只需在主查询中选择LGAvg即可。看起来都铎有你在那里。

编辑:补充说明

让我们获取前两个查询(简化)的输出并进行分析。

您的第一个查询输出如下内容:

Team  |  Down  |  Count
  A        1        18
  A        2        15
  A        3        13
  A        4        11
  B        1        19
  B        2        16
  B        3        13
  B        4        10

你的第二个输出:

Down  |  LGAvg
  1       18
  2       13
  3       11
  4        9

您想将LGAvg添加到第一个查询中。由于我们想要使用子查询,我们可以从查询1中简单地将查询2复制粘贴到SELECT语句中开始。这使我们到达您所在的位置:

Select OffenseTeam, Avg(Togo) as YTG,Down as Downtogo, Down = Case 
when Down =1 Then Count(Down)
when Down =2 Then Count(Down)
when Down =3 Then Count(Down)
when Down =4 Then Count(Down) End,
      (Select Down, Avg(Togo) as YTG
      From Temp_NFL2015
      Where Togo<>0
      Group By Down
      Order By Down ASC) as LGAvg
 From temp_NFL2015
 WHere ToGo <> 0
 Group By OffenseTeam, Down
 Order By OffenseTeam ASC, Downtogo ASC

但现在我们遇到了一些问题:

  • 我们在子查询中选择了2列(DownYTG)。我们不能这样做,因为我们的子查询结果由外部查询中的单个列表示(LGAvg
  • 我们仍然在子查询中使用ORDER BY,这是不允许的,并且无论如何都无法完成任何事情
  • 我们需要提供一个关联,它将定义我们希望内部查询如何连接到外部查询。 这与ON
  • JOIN子句的概念相同

首先,让我们删除ORDER BY

(Select Down, Avg(Togo) as YTG
From Temp_NFL2015
Where Togo<>0
Group By Down) as LGAvg

接下来,让我们开始选择一列YTG。我们必须使当前查询成为派生表,然后才选择YTG

(SELECT YTG FROM ( --Begin derived table
(Select Down, Avg(Togo) as YTG
From Temp_NFL2015
Where Togo<>0
Group By Down)) avgY --End derived table with an alias

快速注意:使用avg作为别名是不好的做法,我不应该这样做,原因很简单,为什么它让你感到困惑。它看起来像AVG()函数,使查询更难理解。我将其更改为avgY以获得平均码数,但您可以按照自己的意愿对其进行别名。

现在我们只是错过了相关性。我们需要添加WHERE avgY.Down = nfl.down,因为这就是我们希望行匹配的方式。我们在派生表的之间进行了这种关联,这使我们得以:

(SELECT YTG 
 FROM (Select Down, Avg(Togo) as YTG
       From Temp_NFL2015
       Where Togo<>0
       Group By Down) avgY
 WHERE avgY.Down = nfl.Down) as LGAvg --avgY and nfl are aliases for inner and outer queries

希望能够清除它。请记住,如果我们将其内容放入临时表(请参阅本答案的顶部),那么我们可以简单地引用临时表,这更容易理解:

  (Select YTG
  From #TEMP avgY
  Where avgY.down = nfl.down) as LGAvg

我们所做的只是在主查询中包含子查询的内容。要证明这一点,请查看如果您将内容粘贴到上方#TEMP上的内容,会发生什么情况!

胆:

(Select Down, Avg(Togo) as YTG
 From Temp_NFL2015
 Where Togo<>0
 Group By Down)

答案 1 :(得分:1)

你想要组合它们的方式不是很清楚,但我的猜测是你想加入关于下降值的两个查询...如果是这样你就是这样做的

 Select OffenseTeam, Avg(l.Togo) as YTG,l.Down as Downtogo, Down = Case 
when l.Down =1 Then Count(l.Down)
when l.Down =2 Then Count(l.Down)
when l.Down =3 Then Count(l.Down)
when l.Down =4 Then Count(l.Down) End 
 From temp_NFL2015 l
 join
 (Select Down, Avg(Togo) as YTG
      From temp_NFL2015 
      Where Togo<>0
      Group By Down) as LGAvg on LGAvg.Down=l.Down

 WHere l.ToGo <> 0
 Group By l.OffenseTeam, l.Down
 Order By l.OffenseTeam ASC, l.Down ASC