在WHERE子句中使用SELECT语句

时间:2011-06-21 11:09:12

标签: sql select where-clause

SELECT * FROM ScoresTable WHERE Score = 
  (SELECT MAX(Score) FROM ScoresTable AS st WHERE st.Date = ScoresTable.Date)

在WHERE子句中是否有使用SELECT语句描述的名称?这是好/坏的做法吗?

这会是一个更好的选择吗?

SELECT ScoresTable.* 
FROM ScoresTable INNER JOIN 
  (SELECT Date, MAX(Score) AS MaxScore 
  FROM ScoresTable GROUP BY Date) SubQuery 
  ON ScoresTable.Date = SubQuery.Date 
  AND ScoresTable.Score = SubQuery.MaxScore

它不那么优雅,但似乎比我以前的版本运行得更快。我不喜欢它,因为它在GUI中没有很清楚地显示(并且需要SQL初学者理解)。我可以将它分成两个单独的查询,但随后事情开始变得混乱......

N.B。我需要的不仅仅是日期和分数(例如姓名)

7 个答案:

答案 0 :(得分:7)

这一点都不错。它们通常称为 SUBQUERY SUBSELECT NESTED QUERY

这是一个相对昂贵的操作,但在处理数据库时遇到很多子查询是很常见的,因为它是对数据执行某种操作的唯一方法。

答案 1 :(得分:6)

它被称为相关子查询。它有它的用途。

答案 2 :(得分:3)

使用SQL Server的analytic (or windowing) functions可以更好地实现所需结果。

SELECT DISTINCT Date, MAX(Score) OVER(PARTITION BY Date) FROM ScoresTable

如果您需要的不仅仅是日期和最高分数组合,您可以使用排名功能,例如:

SELECT  *
FROM    ScoresTable t
JOIN (   
    SELECT 
        ScoreId,
        ROW_NUMBER() OVER (PARTITION BY Date ORDER BY Score DESC) AS [Rank] 
        FROM ScoresTable
) window ON window.ScoreId = p.ScoreId AND window.[Rank] = 1

如果您希望返回多条记录(如果它们共享相同的MAX(分数)),则可能需要使用RANK()而不是ROW_NUMBER()

答案 3 :(得分:2)

子查询的原理并不坏,但我认为你不应该在你的例子中使用它。如果我理解正确,您希望获得每个日期的最高分。在这种情况下,您应该使用GROUP BY。

答案 4 :(得分:1)

  

这是一个相关的子查询。

(这是一个“嵌套”查询 - 虽然这是非技术术语)

内部查询从外部查询(WHERE st.Date = ScoresTable.Date)获取值,因此对外部查询中的每一行计算一次。

还有一种非相关的形式,其中内部查询是独立的,因此只执行一次。

e.g。

 SELECT * FROM ScoresTable WHERE Score = 
   (SELECT MAX(Score) FROM Scores)

使用子查询没有任何问题,除非不需要它们:)

您的语句可以作为聚合函数重写,具体取决于您在select语句中需要的列。

SELECT Max(score), Date FROM ScoresTable 
Group By Date

答案 5 :(得分:1)

在您的案例场景中,为什么不使用GROUP BY和HAVING子句而不是JOINING表给自己。您还可以使用其他有用的功能。 see this link

答案 6 :(得分:0)

子查询是名称。

有时它是必需的,但好/坏取决于它的应用方式。