Вариант переключения в агрегированном запросе

#sql #tsql #aggregate

#sql #tsql #агрегат

Вопрос:

Я хочу иметь switch case в моем SQL-запросе таким образом, чтобы, когда group by не группирует какой-либо элемент, я не хотел агрегировать, иначе я хочу. Возможно ли это.

мой запрос выглядит примерно так:

 select count(1),AVG(student_mark) ,case when Count(1)=1 then student_subjectid else null end from Students
group by student_id
  

я получаю сообщение об ошибке: столбец ‘student_subjectid’ недопустим в списке выбора, поскольку он не содержится ни в агрегатной функции, ни в предложении GROUP BY.

Заранее спасибо..

Комментарии:

1. Сообщение об ошибке стало неактуальным после редактирования исходного кода. Вы должны были добавить к измененному коду своего рода EDIT замечание. В противном случае вам следует удалить или заменить исходное сообщение об ошибке, потому что теперь оно сбивает с толку.

2. о чем ты говоришь? я сам отредактировал исходный код.

3. вы хотите сказать, что я должен был просто оставить свой вопрос как есть и добавить запрос изменений в качестве редактирования..

4. Я говорю об этом сообщении об ошибке, которое вы включили в свой вопрос: Column 'Student_mark' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. я понимаю, что это связано с предыдущей версией вашего запроса. Ваш обновленный скрипт не выдаст эту ошибку.

5. Ну, обычно исходный постер добавляет прогресс, если таковой имеется, в сообщение с вопросом. Я думаю, иногда достаточно просто изменить вопрос (включая любой исходный код), но важно изменить все соответствующие части сообщения, поэтому в целом это имеет смысл.

Ответ №1:

 SELECT
  student_id,
  COUNT(*) AS MarkCount,
  AVG(student_mark) AS student_mark,
  CASE COUNT(*) WHEN 1 THEN MIN(student_subjectid) END AS student_subjectid
FROM Students
GROUP BY student_id
  

Ответ №2:

Зачем, черт возьми, вам это усложнять?

 select count(1), AVG(Student_mark) Student_mark
from Students
group by student_id
  

Если есть только одна студенческая метка, это также СУММА, среднее значение, минимальное и МАКСИМАЛЬНОЕ значение — так что просто продолжайте использовать aggregate!


Редактировать

Набор данных, который соответствовал бы вашему требованию, обычно не имеет смысла. Способ добиться этого — объединить два разных результата

 select
    numRecords,
    Student_mark,
    case when numRecords = 1 then student_subjectid end    # else is implicitly NULL
from
(
select
    count(1) AS numRecords,
    AVG(Student_mark) Student_mark,
    min(student_subjectid) as student_subjectid
from Students
group by student_id
) x
  

Комментарии:

1. это был просто пример.. допустим, я хочу выбрать какое-то другое свойство этого студента в этом случае, например, subjectid тогда?

2. хотя этот soln является самым простым подходом, и я имел это в виду.. для такого небольшого запроса, как этот, это нормально.. но мой фактический запрос включает в себя много join, и я не могу запустить его дважды.. любая другая идея..