Использование результата 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