SQL Различные результаты запроса от Oracle Управляемый поставщик против SQLDeveloper - PullRequest
0 голосов
/ 30 апреля 2020

У меня есть три таблицы, как показано ниже, в базе данных Oracle 11g:

CREATE TABLE courses (
    courseID INTEGER PRIMARY KEY,
    courseName VARCHAR(100),
    limit INTEGER
);

CREATE TABLE students (
    studentID INTEGER PRIMARY KEY,
    Name VARCHAR2(20)
);

CREATE TABLE attends (
    student INTEGER,
    course INTEGER,
    FOREIGN KEY (student) REFERENCES students(studentID),
    FOREIGN KEY (course) REFERENCES courses(courseID),
    CONSTRAINT attends_PK PRIMARY KEY (student, course)
);

и я пытаюсь создать запрос, в котором перечислены все курсы, которые данный студент не посещает в настоящее время, И не полный (например, меньше людей посещают его, чем его предел)

Я сделал следующий запрос для этого:

SELECT c.coursename, c.courseid, c.limit
FROM courses c LEFT JOIN attends a ON a.course = c.courseid
WHERE c.limit > (
    SELECT COUNT(*)
    FROM courses cInner 
    INNER JOIN attends aInner ON cInner.courseid = aInner.course
    WHERE cInner.courseid = c.courseid)
AND a.student <> :studentID OR a.student is null;

Теперь, проверяя это в SQLDeveloper (с заменой: studentID вручную) это работает безупречно. НО, выполняя этот запрос в поставщике Oracle Managed SQL через ADO. Net, возвращаемые строки включают случаи, когда условие ограничения должно быть ложным, даже если я подставляю тот же studentID вручную в строке sql.

Что может вызвать проблему? или что может быть лучше и безопаснее для выполнения такого рода запросов?

Редактировать: пробовал другой запрос с той же целью:

SELECT limit, coursename, courseID FROM (
    SELECT COUNT(a.course) as attends_count, c.courseID, c.limit, c.coursename FROM courses c
    LEFT JOIN attends a ON a.course = c.courseid
    GROUP BY courseID, c.limit, c.coursename)
WHERE limit > attends_count
AND courseID IN (
    SELECT DISTINCT courseID FROM courses
    LEFT JOIN attends ON courseID = attends.course
    WHERE student <> 2 OR student is null
)

, и точно такая же проблема, полный курс также возвращается запросом при выполнении от поставщика C#, и этот альтернативный запрос также работает в SQLDeveloper

1 Ответ

0 голосов
/ 30 апреля 2020

попытайтесь создать запрос, в котором перечислены все курсы, которые данный студент в настоящее время не посещает, И не заполнен (например, меньше людей посещают его, чем его предел)

Это звучит как условная агрегация и сравнение:

SELECT c.coursename, c.courseid, c.limit
FROM courses c LEFT JOIN
     (SELECT COUNT(*) as num_students,
             SUM(CASE WHEN a.student = :studentID THEN 1 ELSE 0 END) as has_student
      FROM attends a
      GROUP BY a.courseId
     ) a
     ON a.course = c.courseid
WHERE a.has_student IS NULL AND
      c.limit > COALESCE(a.num_students, 0)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...