SQL查询帮助第2部分-向联接表添加筛选器并从筛选器中获取最大值

SQL查询帮助第2部分-向联接表添加筛选器并从筛选器中获取最大值,sql,sql-server-2008,Sql,Sql Server 2008,我就这样问了一个问题。不过,我想进一步扩展。例如,我只想在“state”值为“XX”的情况下找到“Reading”列的最大值 因此,如果我连接这两个表,那么如何从结果集中获得具有maxReading值的行。例如 SELECT s.*, g1.* FROM Schools AS s JOIN Grades AS g1 ON g1.id_schools = s.id WHERE s.state = 'SA' // how do I get row with max(Reading) column f

我就这样问了一个问题。不过,我想进一步扩展。例如,我只想在“state”值为“XX”的情况下找到“Reading”列的最大值

因此,如果我连接这两个表,那么如何从结果集中获得具有maxReading值的行。例如

SELECT s.*, g1.*
FROM Schools AS s
JOIN Grades AS g1 ON g1.id_schools = s.id
WHERE s.state = 'SA' // how do I get row with max(Reading) column from this result set
表格详情如下:

Table1 = Schools
    Columns: id(PK), state(nvchar(100)), schoolname

Table2 = Grades
    Columns: id(PK), id_schools(FK), Year, Reading, Writing...
一种方法是:

SELECT...
FROM...
WHERE...
AND g1.Reading = (select max(G2.Reading) 
                  from Grades G2 
                  inner join Schools s2 
                  on s2.id = g2.id_schools
                  and s2.state = s.state)

当然还有更多。

我猜[阅读]是某种形式的数值

SELECT TOP (1)
    s.[Id], 
    s.[State], 
    s.[SchoolName],
    MAX(g.[Reading]) Reading
FROM 
    [Schools] s
    JOIN [Grades] g on g.[id_schools] = s.[Id]
    WHERE s.[State] = 'SA'
Group By 
    s.[Id], 
    s.[State], 
    s.[SchoolName]
Order By 
    MAX(g.[Reading]) DESC
更新: 看看Tom的,我认为这不管用,但这里有一个修改版本

WITH [HighestGrade] (Reading)
AS (
    SELECT
        MAX([Reading]) Reading
    FROM 
        [Grades]
)
SELECT 
    s.*, 
    g.*
FROM 
    [HighestGrade] hg
    JOIN [Grades] AS g ON g.[Reading] = hg.[Reading]
    JOIN [Schools] AS s ON s.[id] = g.[id_schools]
    WHERE s.state = 'SA'

我会考虑使用一个通用的表表达式:

WITH SchoolsInState (id, state, schoolname)
AS (
    SELECT id, state, schoolname
    FROM Schools
    WHERE state = 'XX'
)
SELECT *
FROM SchoolsInState AS s
JOIN Grades AS g
ON s.id = g.id_schools
WHERE g.Reading = max(g.Reading)

这样做的好处是,它创建了SchoolsInState伪表,其中包含了有关按状态筛选的所有逻辑,让您可以自由编写查询的其余部分,而无需考虑它。

此CTE方法应该可以满足您的需要。我还让它在我的代码中按年份进行分解,以避免保留字。如果你想的话,你应该能够很容易地移除它。此方法还考虑了关系如果存在关系,您将返回两行:

;WITH MaxReadingByStateYear AS (
    SELECT
        S.id,
        S.school_name,
        S.state,
        G.grade_year,
        RANK() OVER(PARTITION BY S.state, G.grade_year ORDER BY Reading DESC) AS ranking
    FROM
        dbo.Grades G
    INNER JOIN Schools S ON
        S.id = G.id_schools
)
SELECT
    id,
    state,
    school_name,
    grade_year
FROM
    MaxReadingByStateYear
WHERE
    state = 'AL' AND
    ranking = 1

添加的select语句仍然只返回具有总最大读取值的行。我只想要具有特定状态的最大读取值的行。公平点。以上答案更正。但您似乎只需将内部选择限制为外部选择中指定的状态。可能存在多行具有相同最大值的情况。我支持子查询上的CTE方法,因为它避免了每次迭代都需要重新评估查询。可能存在多行具有相同最大值的情况最大值,但只能有一个最大值,因此可以使用=而不是in。而且,U2C,我们的查询做了不同的事情:我的查询找到了给定州中分数最高的学校;你的学校可以找到全球分数最高的学校,但前提是它在给定的州。我想。汤姆,我不认为在where子句中使用聚合函数是有效的。谢谢汤姆-cte的使用让我过火了。然而,used2can是正确的,您不能在where子句中使用agregate函数。最后,我加入了cte,并从学校选择了*,其中s.在选择maxs中阅读。从学校阅读。噢,对不起,伙计们,你们当然是对的。在发布之前,我手头没有可靠的PostgreSQL来检查我的查询。赛斯,我猜你现在基本上是在做一个等级学校安装CTE,是的,这让整个事情变得非常简单。我开始考虑各种各样的相关子查询的东西。在你的下一个作业中,你如何获得每个州的顶尖学校名单