我有一个像这样的SQL架构
“考试”表
+--------------+----------+-------------+--------+
| EXAM_ID (PK) | PERSONID | DATEOFSTART | SECRET |
+--------------+----------+-------------+--------+
| 1 | 221 | 2016-01-24 | 0 |
| 2 | 221 | 2017-06-03 | 0 |
| 3 | 221 | 2016-09-17 | 1 |
+--------------+----------+-------------+--------+
“Exam_information”表
+---------------+------------------+---------+-------+
| PERSONID (PK) | DATEOFSTART (PK) | SUBJECT | SCORE |
+---------------+------------------+---------+-------+
| 221 | 2016-01-24 | Math | A |
| 221 | 2017-06-03 | Biology | B |
| 221 | 2016-09-17 | Math | C+ |
+---------------+------------------+---------+-------+
因此,考试可以在Exam_information
表格中提供其他信息。我知道这不是正确设计的架构,但我无法修改它。
最终,我想知道考试不是秘密的人的所有分数。我将逐步构建我的DML,但让我们从基本的JOIN
操作开始。
SELECT ei.*
FROM exam_information ei
INNER JOIN exam e
ON ei.personid = e.personid
WHERE ei.personid = 221
这将返回9行数据(因为笛卡尔加入/交叉连接),所以让我们在DISTINCT
语句中使用SELECT
。
SELECT DISTINCT ei.*
FROM exam_information ei
INNER JOIN exam e
ON ei.personid = e.personid
WHERE ei.personid = 221
这将返回3行数据,因此我们似乎在正确的轨道上。我们知道返回3行的其中一行是秘密的,并希望将其排除在外。创建了DML的最终版本。
SELECT DISTINCT ei.*
FROM exam_information ei
INNER JOIN exam e
ON ei.personid = e.personid
WHERE ei.personid = 221
AND e.secret = 0
不知何故(我不是任何SQL大师)这会返回与之前的DML相同的行。三。不像我想的那样两个。
如果我将secret
字段添加到我之前的SELECT
语句SELECT DISTINCT e.secret, ei.* FROM ...
中,我会看到所有3个返回的行都有一个零值作为秘密值,这根本不是真的
我尝试了各种各样的东西,但似乎没有任何效果。
答案 0 :(得分:0)
你的连接部分关系总是返回3行,因为这个返回3行的
ON ei.personid = e.personid
WHERE ei.personid =
如果您只想要具有秘密0的行,则必须使用dateofstart链接单行
SELECT DISTINCT ei.*
FROM exam_information ei
INNER JOIN exam e
ON ei.personid = e.personid and ei.DATEOFSTART = e.DATEOFSTART
WHERE ei.personid = 221
AND e.secret = 0
答案 1 :(得分:0)
你正在考试中将所有3个考试信息中的EACH记录加入考试中,所以即使你排除了那个秘密的ONE,它仍然会检测到其他2条记录,制作了6条记录,这些记录明显地被归为3条。重新缺少JOIN的标准(作为dateofstart),它将exam_information中的每条记录与考试中的SINGLE记录相匹配,从而允许WHERE过滤器正常工作。
SELECT DISTINCT ei.*
FROM exam_information ei
INNER JOIN exam e
ON ei.personid = e.personid AND ei.dateofstart = e.dateofstart
WHERE ei.personid = 221
AND e.secret = 0
答案 2 :(得分:0)
这个:
SELET DISTINCT ei.* FROM EXAM_INFORMATION ei
INNER JOIN
(SELECT PERSON_ID, DATEOFSTART FROM EXAM WHERE SECRET = 0) a
ON a.PERSON_ID = ei.PERSON_ID and ei.DATEOFSTART = a.DATEOFSTART
WHERE ei.PERSON_ID = 221;
内表将选择所有没有秘密的考试数据。然后在信息表上执行选择,将其加入内部表 - 这将为您提供非秘密考试数据的所有考试信息,然后最后过滤person_id。