SQLinfo.ru - Все о MySQL Webew.ru: теория и практика веб-технологий

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 17.01.2010 15:39:41

refoxt
Участник
Зарегистрирован: 11.01.2010
Сообщений: 11

Деление отношений

Значит имеется бд:
STUDENT {ID_STUDENT, FAMIL, SCHOOL, CLAS, PREPOD}
     primary key {ID_STUDENT}

TASK {ID_TASK, TASK_INFO}
     primary key {ID_TASK}

GRADE_TO_TASK {ID_STUDENT, ID_TASK, GRADE}
     primary key {ID_STUDENT, ID_TASK}

Нужно реализовать операцию реляционной алгебры деление отношений.

Нужно найти студентов, у которых стоят все возможные оценки.(к примеру у отличников нет 2 и наоборот)
Получается множество студентов с оценками разделить на множество всех возможных оценок.

На одном сайте нашел :

SELECT DISTINCT A.X
  FROM A
  WHERE NOT EXIST
    (SELECT *
        FROM B
        WHERE NOT EXIST
          (SELECT *
              FROM A A1
              WHERE
                  A1.X = A.X AND
                  A1.Y = B.Y));

Тут проблем нет перенес на свою базу получилось и работает, но почему и как понять не могу sad

SELECT DISTINCT id_student
                    FROM grade_to_task AS A
                    WHERE NOT
                    EXISTS (
                    SELECT *
                    FROM (
                    SELECT DISTINCT grade
                    FROM grade_to_task
                    ) AS B
                    WHERE NOT
                    EXISTS (
                    SELECT *
                    FROM grade_to_task AS A1
                    WHERE A1.id_student = A.id_student
                    AND A1.grade = B.grade
                    ))

на другом сайте нашел еще одну реализацию оператора деления, уже поинтересней и мне более понятную:

A DEVIDE BY B = A[X] MINUS ((A[X] TIMES B) MINUS A)[X]


Но вот запрос правильно написать не могу sad

SELECT DISTINCT id_student FROM (
SELECT * FROM (
SELECT *
FROM (SELECT DISTINCT id_student from grade_to_task) as T1,
           (SELECT DISTINCT grade from grade_to_task) as T2
) as T3
WHERE NOT EXISTS (SELECT id_student, grade FROM grade_to task)
) AS T0
WHERE NOT EXISTS (SELECT id_student from grade_to_task)

По моему выдает ошибку на первом NOT EXISTS

Помогите плз разобраться.

Отредактированно refoxt (17.01.2010 18:49:41)

Неактивен

 

#2 18.01.2010 14:25:17

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Деление отношений

У Вас очень странное решение и странный подход. Кажется, в MySQL
эта задача решается простыми операциями:

SELECT ID_STUDENT, GROUP_CONCAT(DISTINCT GRADE) AS marks
FROM GRADE_TO_TASK
GROUP BY ID_STUDENT
HAVING marks = '1,2,3,4,5';

Найдет студентов с оценками от «кола» до «отлично».

Неактивен

 

#3 18.01.2010 15:21:49

refoxt
Участник
Зарегистрирован: 11.01.2010
Сообщений: 11

Re: Деление отношений

хм не спорю что странно но ...
у меня в контрольной надо реализовать 8 операций Кода
деление одна из них

я просто для примера взял множество оценок,
а ведь это множество мб и изменчиво.(или к примеру по 100 шкале тоже мало приятного писать)

и пжлст объясните почему последний запрос не работает
мб я в синтаксисе ошибся

Неактивен

 

#4 18.01.2010 15:34:36

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Деление отношений

Ошибка в логике. У Вас написано следующее

SELECT … FROM ( () t1, () t2) t3.

Его смущает, что два алиаса без явной операции объединения еще и
пытаются заалиаситься. Он просто не знает, что с этим делать. Попробуйте
написать через JOIN — и в синтаксисе не ошибетесь, и себе будет понятнее,
что делаете.

Неактивен

 

#5 18.01.2010 15:57:23

refoxt
Участник
Зарегистрирован: 11.01.2010
Сообщений: 11

Re: Деление отношений

что то не получается sad


 SELECT *
 FROM (
            SELECT *
            FROM (
                       SELECT DISTINCT id_student
                       FROM grade_to_task) AS t1
              JOIN (
                       SELECT DISTINCT grade
                       FROM grade_to_task) AS t2
) AS t3
WHERE NOT EXISTS (
                                   SELECT * FROM grade_to_task)
 


Результат в любом случае один и тот же sad
 

Impossible WHERE noticed after reading const table...

Неактивен

 

#6 18.01.2010 16:19:26

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Деление отношений

Надо было не бездумно заменить, а подумать, что хочется сделать, и потом
уже сделать.

А оптимизатор у Вас абсолютно прав, он смотрит на ваш агрегат, в котором
написано в конце «где нет строк в grade_to_task», и говорит «строки есть,
запрос пустой, всё хорошо».

Неактивен

 

#7 18.01.2010 17:43:19

refoxt
Участник
Зарегистрирован: 11.01.2010
Сообщений: 11

Re: Деление отношений

Все, вроде бы дошло
мой 1й запрос уже делает все как надо, просто чего то я его сразу нe разобрал hmm

делал делал и доделал вот до такого


SELECT DISTINCT id_student
FROM grade_to_task AS t1
WHERE NOT
EXISTS (

SELECT grade
FROM grade_to_task AS t2
WHERE NOT
EXISTS (

SELECT id_student, grade
FROM grade_to_task t3
WHERE t3.id_student = t1.id_student
AND t3.grade = t2.grade
)
)
 

smile

ну спасиб за помощь

Неактивен

 

#8 18.01.2010 17:54:01

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Деление отношений

Кажется, Вы написали тот же запрос, что был Вам не понятен в начале wink

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson