【问题标题】:SQL Different query results from Oracle Managed Provider vs. SQLDeveloperSQL Oracle Managed Provider 与 SQLDeveloper 的不同查询结果
【发布时间】:2020-08-14 03:21:06
【问题描述】:

我在 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),它可以完美运行。 但是通过 ADO.Net 在 Oracle Managed SQL 提供程序中执行此查询,返回的行包括限制条件应该为假的情况,即使我直接在 sql 字符串中手动替换相同的 studentID。

什么会导致问题?或者有什么更好、更安全的方法来进行这种查询?

编辑:出于相同目的尝试了另一个查询:

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

【问题讨论】:

    标签: sql oracle oracle11g


    【解决方案1】:

    尝试创建一个查询,列出给定学生当前未参加且未满的所有课程(例如,参加该课程的人数超过其限制)

    这听起来像是条件聚合和比较:

    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)
    

    【讨论】:

      猜你喜欢
      • 2013-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多