Использование результата SELECT в другом SELECT
Проблема с SQL-запросом для получения средней оценки за последние 3 месяца
Я пытаюсь создать SQL-запрос, который возвращает результаты для таблицы лидеров в формате GridView. Моя цель — получить среднее значение оценок, которые были выставлены за последние 3 месяца.
Вот мой первоначальный запрос:
SELECT
*
FROM
Score AS NewScores
WHERE
InsertedDate >= DATEADD(mm, -3, GETDATE());
SELECT
ROW_NUMBER() OVER( ORDER BY NETT) AS Rank,
Name,
FlagImg,
Nett,
Rounds
FROM (
SELECT
Members.FirstName + ' ' + Members.LastName AS Name,
CASE
WHEN MenuCountry.ImgURL IS NULL THEN
'~/images/flags/ismygolf.png'
ELSE
MenuCountry.ImgURL
END AS FlagImg,
AVG(CAST(NewScores.NetScore AS DECIMAL(18, 4))) AS Nett,
COUNT(Score.ScoreID) AS Rounds
FROM
Members
INNER JOIN
Score
ON Members.MemberID = Score.MemberID
LEFT OUTER JOIN MenuCountry
ON Members.Country = MenuCountry.ID
WHERE
Members.Status = 1
GROUP BY
Members.FirstName + ' ' + Members.LastName,
MenuCountry.ImgURL
) AS Dertbl
ORDER BY;
Однако при выполнении этого запроса возникает ошибка:
Msg 4104, Level 16, State 1, Line 2
The multi-part identifier "NewScores.NetScore" could not be bound.
Эта ошибка возникает из-за строчки:
AVG(CAST(NewScores.NetScore AS DECIMAL(18, 4))) AS Nett
Мне нужно использовать NewScores, чтобы я мог получать только среднее значений оценок за последние 3 месяца.
Вопрос:
Как мне изменить запрос, чтобы я мог использовать NewScores и получить среднее значение оценок только тех, которые были выставлены меньше 3 месяцев назад?
Редактирование:
Используя предоставленные ответы, я успешно решил проблему, добавив необходимое соединение в правильном месте. Вот исправленный запрос:
SELECT
ROW_NUMBER() OVER(ORDER BY NETT) AS Rank,
Name,
FlagImg,
Nett,
Rounds
FROM (
SELECT
Members.FirstName + ' ' + Members.LastName AS Name,
CASE
WHEN MenuCountry.ImgURL IS NULL THEN
'~/images/flags/ismygolf.png'
ELSE
MenuCountry.ImgURL
END AS FlagImg,
AVG(CAST(NewScores.NetScore AS DECIMAL(18, 4))) AS Nett,
COUNT(NewScores.ScoreID) AS Rounds
FROM
Members
INNER JOIN (
SELECT *
FROM Score
WHERE InsertedDate >= DATEADD(mm, -3, GETDATE())
) AS NewScores
ON Members.MemberID = NewScores.MemberID
LEFT OUTER JOIN MenuCountry
ON Members.Country = MenuCountry.ID
WHERE
Members.Status = 1
GROUP BY
Members.FirstName + ' ' + Members.LastName,
MenuCountry.ImgURL
) AS Dertbl
ORDER BY Nett ASC;
Теперь запрос работает корректно.
3 ответ(ов)
Ваш запрос можно объединить для улучшения читаемости и производительности. Попробуйте следующий вариант:
SELECT
ROW_NUMBER() OVER (ORDER BY Nett) AS Rank,
Name,
FlagImg,
Nett,
Rounds
FROM (
SELECT
Members.FirstName + ' ' + Members.LastName AS Name,
COALESCE(MenuCountry.ImgURL, '~/images/flags/ismygolf.png') AS FlagImg,
AVG(CAST(NewScores.NetScore AS DECIMAL(18, 4))) AS Nett,
COUNT(NewScores.ScoreID) AS Rounds
FROM
Members
INNER JOIN
Score NewScores ON Members.MemberID = NewScores.MemberID
LEFT JOIN
MenuCountry ON Members.Country = MenuCountry.ID
WHERE
Members.Status = 1
AND NewScores.InsertedDate >= DATEADD(month, -3, GETDATE())
GROUP BY
Members.FirstName + ' ' + Members.LastName,
MenuCountry.ImgURL
) AS Dertbl
ORDER BY Nett;
В этом запросе я использовал функцию COALESCE, чтобы упростить обработку значений NULL для флага страны. Также исправил часть с чтением поля ScoreID в COUNT, чтобы избежать путаницы. Пожалуйста, убедитесь, что имена таблиц и столбцов корректны и соответствуют вашей схеме базы данных.
Что вам нужно, так это запрос с использованием конструкции WITH, если ваша СУБД это поддерживает. Тогда ваш запрос будет выглядеть так:
WITH NewScores AS (
SELECT *
FROM Score
WHERE InsertedDate >= DATEADD(mm, -3, GETDATE())
)
SELECT
<и остальная часть вашего запроса>
Обратите внимание, что в первой части нет ;. Надеюсь, это поможет!
Вы пропустили таблицу NewScores, поэтому она не может быть найдена. Просто объедините эту таблицу.
Если вы действительно хотите избежать прямого соединения, вы можете заменить NewScores.NetScore на SELECT NetScore FROM NewScores WHERE {условия, по которым они должны совпадать}.
Обновление данных в одной таблице из другой на основе совпадения ID
SQL SELECT WHERE поле содержит слова
with(nolock) или (nolock) - есть ли разница?
Возможно ли задать условия в Count()?
Параметризованные запросы с условиями LIKE и IN