Справка по SQL-запросам, часть 2. Добавление фильтра к объединенным таблицам и получение максимального значения из фильтра - PullRequest
0 голосов
/ 15 июня 2010

Я задал этот вопрос на SO. Тем не менее, я хотел бы расширить его дальше. Я хотел бы найти максимальное значение столбца «Чтение», только если «состояние» имеет значение «ХХ», например.

Так что, если я соединю две таблицы, как мне получить строку со значением 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 ]

2 голосов
/ 15 июня 2010

Я бы подумал об использовании общего табличного выражения:

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, которая оборачивает всю логику фильтрации по состоянию, позволяя вам написать оставшуюся часть запроса, не думая об этом.

0 голосов
/ 15 июня 2010

Этот метод 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
0 голосов
/ 15 июня 2010

Я предполагаю, что [Чтение] является некоторой формой числового значения.

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'
0 голосов
/ 15 июня 2010

Один из способов был бы таким:

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)

Есть, конечно, больше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...