尝试从 SQL 请求中获取表

Posted

技术标签:

【中文标题】尝试从 SQL 请求中获取表【英文标题】:Attempting to get a table from SQL Request 【发布时间】:2019-03-05 18:24:05 【问题描述】:

我现在正在做一个项目,我需要通过 SQL *PLUS 向我的数据库提出一些请求。

这就是我想要做的。 我想得到一张表,在其中我得到带有这些条件的教授名字和姓氏(我必须验证第一个条件,然后是另一个):

(首先)在一个会话中(比如说 12004),一位教授确实教授了这两门课程,INF3180INF2110

(第二次)在另一个课程 32003 中,一位教授确实教授了这两门课程,INF1130INF1110

这是创建数据库的代码:

CREATE TABLE Professor
(professorCode  CHAR(5) NOT NULL,
 lastName           VARCHAR(10) NOT NULL,
 firstName      VARCHAR(10) NOT NULL,
 CONSTRAINT PrimaryKeyProfessor PRIMARY KEY     (professorCode)
)
;

CREATE TABLE Group
(sigle      CHAR(7)     NOT NULL,
 noGroup    INTEGER     NOT NULL,
 sessionCode INTEGER        NOT NULL,
 maxInscriptions    INTEGER     NOT NULL,
 professorCode  CHAR(5) NOT NULL,
CONSTRAINT PrimaryKeyGroup PRIMARY KEY   
(sigle,noGroupe,sessionCode),
CONSTRAINT CESigleGroupeRefCours FOREIGN KEY    (sigle) REFERENCES Cours,
CONSTRAINT CECodeSessionRefSession FOREIGN KEY  (sessionCode) REFERENCES 
Session,
CONSTRAINT CEcodeProfRefProfessor FOREIGN KEY(professorCode) REFERENCES 
Professor
) 
;

这是我目前不工作的请求:

SELECT DISTINCT Professor.firstName, Professor.lastName
FROM            Professor, Group
WHERE           Group.professorCode = Professor.professorCode
                AND Group.sessionCode = 32003
                AND (Group.sigle = 'INF1130' AND
                     Group.sigle = 'INF1110')
                OR Group.sessionCode = 12004 
                AND (Group.sigle = 'INF3180' AND
                     Group.sigle = 'INF2110')

我知道有一种方法可以将这两个结果结合起来,但我似乎找不到。

在这种情况下只有一个匹配项

只有一个匹配 32003 : INF1130, INF1110 与 12004 不匹配:INF3180、INF2110

结果表应该如下所示:

--------------------------
First Name       Last Name
--------------------------
Denis            Tremblay

Gordon Linoff 提出的解决方案看起来非常好,除了它没有返回任何表格,因为使用以下代码,它需要包含 4 个课程和 2 个 sessionCode。这里的问题是它需要验证条件并附加结果。假设会话 12004 的条件没有结果,那么我可以将其视为 NULL。然后,第二个条件,会话 32003,给了我一个匹配。它应该附加两个结果,给我提供的表格。

我只想为此做一个请求。

非常感谢!

编辑:重新制定

EDIT2:举一个已知匹配的例子

EDIT3:进一步解释为什么建议的解决方案不起作用

【问题讨论】:

不确定 Oracle 或 sql plus,但您可能正在寻找存在的位置或位置。因为一条记录不能同时满足这两个条件。 请提供符合条件和不符合条件的教授示例。 只有一位教授与请求匹配。它只响应 INF1110、INF1130 和 32003。没有一个匹配 INF3180、INF2110 和 12004。它必须显示匹配的那个 刚刚添加了一个例子! @GordonLinoff 如果不匹配示例输入,示例输出将无济于事 - 包括应该出现在结果集中的数据。您说您的查询“不起作用”,但这意味着什么 - 您是否遇到错误?结果太多?不够?请在您的问题中包含当前结果以及示例数据,并解释错误的原因。 【参考方案1】:

想想:group byhaving。更重要的是,想想JOINJOINJOIN永远不要from 子句中使用逗号。

SELECT p.firstName, p.lastName
FROM Professor p JOIN
     Group g
     ON g.professorCode = p.professorCode
WHERE (g.sessionCode, g.sigle) IN ( (32003, 'INF1130'), (32003, 'INF1110'),
                                    (12004, 'INF3180'), (12004, 'INF2110')
                                  )
GROUP BY p.firstName, p.lastName
HAVING COUNT(DISTINCT g.sigl) = 4;  -- has all four

【讨论】:

这里是翻译后的问题:我们搜索老师的代码和名字,不重复,在代码为12004的课程中同时教过INF3180和INF2110。另外,代码和教过INF1130或INF1110课程的教师姓名,课程期间代码为32003 @GuillaumeLevesque。 . .这四个条件是教授教授所有四个课程。这就是这个查询的作用。 对不起,英语不是我的主要语言。我必须返回的表是在 32003 年教 INF1130 和 INF1110 的老师和在 12004 年教 INF3180 和 INF2110 的老师。我的错,我无法正确表达自己:/【参考方案2】:

您似乎想列出在 32003 中任一教授 INF1130 和 INF1110 的任何教授;或在 12004 年教授 INF3180 和 INF2110。不幸的是,您将其呈现为 AND(即他们必须教授所有四门课程 - 一对课程和另一门),而不是 OR(一组课程或另一门)。

作为扩展我认为您想要的内容的冗长方式:

SELECT p.firstName, p.lastName
FROM Professor p
WHERE (
  EXISTS (
    SELECT *
    FROM GroupX g
    WHERE professorCode = p.professorCode
    AND sessionCode = 32003
    AND sigle = 'INF1130'
  )
  AND EXISTS (
    SELECT *
    FROM GroupX g
    WHERE professorCode = p.professorCode
    AND sessionCode = 32003
    AND sigle = 'INF1110'
  )
)
OR (
  EXISTS (
    SELECT *
    FROM GroupX g
    WHERE professorCode = p.professorCode
    AND sessionCode = 12004
    AND sigle = 'INF3180'
  )
  AND EXISTS (
    SELECT *
    FROM GroupX g
    WHERE professorCode = p.professorCode
    AND sessionCode = 12004
    AND sigle = 'INF2110'
  )
);

四个子查询不会非常有效。您可以改为执行多个联接。

如果您总是要为每个 sessionCode 寻找两个 sigle 值,那么您可以修改 Gordon 的答案以计算每个 sigle 有多少匹配项,方法是将其添加到 group-by 子句中:

SELECT p.firstName, p.lastName
FROM GroupX g
JOIN Professor p
ON p.professorCode = g.professorCode
WHERE (g.sessionCode, g.sigle) IN ( (32003, 'INF1130'), (32003, 'INF1110'),
                                    (12004, 'INF3180'), (12004, 'INF2110')
                                  )
GROUP BY p.firstName, p.lastName, g.sessionCode
HAVING COUNT(*) = 2;

如果您确实有一位教授所有这四个方面的教授,那么您会将他们列出两次;如果发生这种情况,您可以重新添加您的DISTINCT,尽管感觉有点不对。您还可以使用子查询和IN 来避免这种情况:

SELECT p.firstName, p.lastName
FROM Professor p
WHERE ProfessorCode IN (
  SELECT professorCode
  FROM GroupX
  WHERE (sessionCode, sigle) IN ( (32003, 'INF1130'), (32003, 'INF1110'),
                                  (12004, 'INF3180'), (12004, 'INF2110')
                                )
  GROUP BY professorCode, sessionCode
  HAVING COUNT(*) = 2
)

(我已将 Group 更改为 GroupX,因为这不是有效的标识符;因为它是一个关键字。我假设您已经更改了您的真实姓名 - 可能是另一种语言?)

【讨论】:

工作得非常好。我知道我做错了什么。非常感谢所有帮助过我的人! 是的,来自法语【参考方案3】:

使用现代连接

SELECT Professor.firstName, Professor.lastName
FROM            Professor join "Group" g on
            g.professorCode = Professor.professorCode
               where  g.sessionCode in( 32003,12004 )
                AND g.sigle in( 'INF1130', 'INF1110','INF3180','INF2110')                        
             group by  Professor.firstName, Professor.lastName
             having count( distinct sigle )=4

【讨论】:

以上是关于尝试从 SQL 请求中获取表的主要内容,如果未能解决你的问题,请参考以下文章

获取 ajax 请求以更新 SQL 表中的列

从sql请求中获取返回值

从 PHP 请求名称为分音符号的 MS SQL 表

如何使用 SQL 和 PHP 从数据库 (phpMyAdmin) 的字段中获取/请求所有值?

客户端无权发出此请求 - 在尝试通过 java 获取 google cloud sql 实例时

从一张桌子获取待处理的好友请求