SQL查询帮助第2部分 - 向连接的表添加过滤器并从过滤器获取最大值

时间:2010-06-15 12:28:08

标签: sql sql-server-2008

我问过this问题。但是,我希望进一步扩展它。我想找到'Reading'列的最大值,只有'state'的值为'XX'才是。

因此,如果我加入两个表,如何从结果集中获取具有max(读取)值的行。例如

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...

4 个答案:

答案 0 :(得分:2)

我考虑使用公用表表达式:

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伪表,它包含了所有关于按状态过滤的逻辑,让你可以自由地编写查询的其余部分,而不必考虑它。

答案 1 :(得分:0)

一种方式是:

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)

当然还有更多。

答案 2 :(得分:0)

我猜[Reading]是某种形式的数值。

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

UPDATE:

看着汤姆,我认为这不会起作用,但这是一个修改过的版本。

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'

答案 3 :(得分:0)

这种CTE方法应该能满足您的需求。我也按年分解(我的代码中的grade_year以避免保留字)。如果你愿意,你应该能够轻松地删除它。这种方法也考虑了关系(如果存在平局,你会得到两行):

;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