Как использовать символ «меньше» или «больше чем» в операторе WHERE с функцией SUM - PullRequest
0 голосов
/ 23 сентября 2011

Я хочу перечислить записи, если общее число Да меньше 5.

Я получаю ошибку:

Агрегат может не отображаться в предложении WHERE, если только он не входит в подзапрос, содержащийся в предложении HAVING или списке выбора, а агрегируемый столбец является внешней ссылкой

Я хочу перечислить студентов, которые учатся в WCM103 и посещали менее 5 классов.

Ответы [ 3 ]

2 голосов
/ 23 сентября 2011

Хотелось бы что-то вроде:

WITH att
  AS (SELECT studentID, 
             SUM(CASE WHEN attStatus = 'Yes' THEN 1 ELSE 0 END) as att_count
        FROM attendance
       GROUP BY studentID)
SELECT *
  FROM Attendance a 
 INNER JOIN Student s USING (studentID)
 INNER JOIN att USING (studentID)
 WHERE att.att_count < 5
   AND a.unitcode = 'SIT103';

работаешь на тебя?

Вы можете выбрать нужные вам столбцы из СТУДЕНТА, ВНИМАНИЯ и т. Д.

РЕДАКТИРОВАТЬ: у меня нет интерфейса SQL передо мной, поэтому некоторые из SQL может потребоваться настройка.

Дэвид, в свете новой информации, попробуйте следующее:

WITH att
  AS (SELECT unitcode,
             studentID, 
             SUM(CASE WHEN attStatus = 'Yes' THEN 1 ELSE 0 END) as att_count
        FROM attendance
       WHERE attdate < TO_DATE('07/08/2011', 'DD/MM/YYYY')
       GROUP BY unitcode,
                studentID)
SELECT *
  FROM Student s
 INNER JOIN att USING (studentID)
 WHERE att.unitcode = 'SIT103'
   AND att.att_count < 5;

У меня теперь работает SQL * Plus. Я только что побежал:

CREATE TABLE student (
  studentid NUMBER,
  student_name VARCHAR2(30)
);

CREATE TABLE attendance (
  studentid NUMBER,
  unitcode VARCHAR2(10),
  attdate  DATE,
  attstatus VARCHAR2(5)
);

INSERT INTO student VALUES (2106,'Jo Bloggs');
INSERT INTO student VALUES (2108,'Jo Schmoe');

INSERT INTO attendance VALUES (2106, 'SIT103', TO_DATE('05/06/2011', 'DD/MM/YYYY'), 'No');
INSERT INTO attendance VALUES (2106, 'SIT103', TO_DATE('07/07/2011', 'DD/MM/YYYY'), 'Yes');
INSERT INTO attendance VALUES (2106, 'SIT103', TO_DATE('10/05/2011', 'DD/MM/YYYY'), 'Yes');
INSERT INTO attendance VALUES (2108, 'SIT203', TO_DATE('05/05/2011', 'DD/MM/YYYY'), 'Yes');

WITH att
  AS (SELECT unitcode,
             studentID, 
             SUM(CASE WHEN attStatus = 'Yes' THEN 1 ELSE 0 END) as att_count
        FROM attendance
       WHERE attdate < TO_DATE('07/08/2011', 'DD/MM/YYYY')
       GROUP BY unitcode,
                studentID)
SELECT studentid,
       student_name,
       unitcode
  FROM Student s
 INNER JOIN att USING (studentID)
 WHERE att.unitcode = 'SIT103'
   AND att.att_count < 5;

и получил:

STUDENTID STUDENT_NAME UNITCODE
2106         Jo Schmoe    SIT103  

Что правильно, не так ли?

1 голос
/ 23 сентября 2011

Чтобы использовать команду «иметь», необходимо иметь предложение group by, затем группа «by» выполняется, и после того, как запрос был агрегирован, он становится фильтром.

Не уверен, что вы хотите сделать сумму, не видя данных в таблицах, но вы должны быть в состоянии сделать подсчет числа да в таблице посещаемости, а затем наличие перечислит тех, которые соответствуют критериям

Попробуйте что-то вроде этого (Oracle SQLсинтаксис)

SELECT s.studentname, count(*)
  FROM student s, attendance a
 WHERE s.studentid=a.studentid
   AND a.class='SIT108'
   AND a.status='Y'
 GROUP BY s.studentname
HAVING COUNT(*)<5

или с синтаксисом ANSI

SELECT s.studentname, count(*)
  FROM student s
  LEFT INNER JOIN attendance a
    ON s.studentid=a.studentid
 WHERE a.class='SIT108'
   AND a.status='Y'
 GROUP BY s.studentname
HAVING COUNT(*)<5

Вы также можете опустить счетчик (*) в верхней строке, если вам нужен только список имен

SELECT s.studentname
  FROM student s
  LEFT INNER JOIN attendance a
    ON s.studentid=a.studentid
 WHERE a.class='SIT108'
   AND a.status='Y'
 GROUP BY s.studentname
HAVING COUNT(*)<5

Добавьте любые дополнительные пункты или объединения, где вам нужно

0 голосов
/ 23 сентября 2011

Попробуйте заменить WHERE на HAVING, как показано ниже:

SELECT        * 
FROM            Attendance AS a INNER JOIN
                         Student AS s ON a.studentID = s.studentID
HAVING        (SUM(CASE WHEN attStatus = 'Yes' THEN 1 ELSE 0 END) < 5)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...