我想从数据库中导出一些数据。
基本上我想说的是:
1-从members
表中选择mbr_name
2-选择存在于course_registration
表中的值(基于mbr_id
)
3-将course_registration
标识与course_comments
表联接
然后,我还需要应用这些WHERE条件:
1-请确保course_registration
表中的crr_status
设置为**completed
**
2-请确保course_registration
表中的crr_ts
介于**"2021-03-07 00:00:00"
与"2022-03-17 00:00:00"
之间
3-请确保将course_comments
表中的crm_confirmation
设置为accept
**
所以我尽了最大的努力写了这句话:
SELECT members.mbr_name
FROM members
INNER JOIN course_registration AS udt ON members.mbr_id = udt.crr_mbr_id
INNER JOIN course_comments AS dot ON udt.crr_cor_id = dot.crm_reference_id
WHERE udt.crr_status = "completed" AND udt.crr_ts >= "2021-03-07 00:00:00" AND udt.crr_ts < "2022-03-17 00:00:00"
AND dot.crm_confirmation = "accept";
但这会以某种方式给予错误的数据。
具有所有这些条件的members
的实际数量是12 K,但是这个查询给了我120 K的结果,这显然是错误的!
那么,这里出了什么问题?我该如何解决这个问题?
更新:
以下是每个表的键:
members (mbr_id (PK), mbr_name)
course_registration (crr_id (PK), crr_mbr_id (FK), crr_cor_id (FK), crr_status)
course_comments (crm_id (PK), crm_reference_id (FK), crm_confirmation)
6条答案
按热度按时间kqlmhetl1#
您遇到了所谓的基数问题。当一个表中的多行与另一个表中的一行匹配时,JOIN可能会导致结果集具有多行。您所编写的JOIN将生成许多行:成员x课程x评论。这就是JOIN的作用。
看起来您希望结果集中的每个成员都正好有一行...
因此,让我们从一个子查询开始,它为那些对一个或多个符合您的标准的课程提交了一个或多个评论的成员提供
mbr_id
值。您可以使用该子查询的结果来查找成员。
c2e8gylq2#
由于您只想选择成员名称,如果这能给出所需的结果,您可以尝试以下操作
qlckcl4x3#
在不了解上下文的情况下,我的第一个猜测是:
如果是这种情况,由于冗余,你会得到更多的元组。在这种情况下,你只需要在你的第一个SELECT之后粘贴一个
DISTINCT
。此外,由于
JOIN
是sql中最耗费资源的操作,我将首先过滤数据,然后将join作为最后一个操作以提高效率。pwuypxnk4#
我会先从注册开始,而不是从会员开始。通过得到一个注册课程的会员的DISTINCT列表,你就得到了一个较小的子集。从这个子集开始,加入那些被接受的会员的评论,你就得到了一个最终的列表。
一旦你有了这两个,加入回成员,以获得名称。我包括成员ID以及名称,因为如果你有两个或更多的“约翰”或“卡伦”的名字在注册。至少你有ID,以确认唯一的学生。
oipij1gg5#
试试看:
dced5bon6#
请尝试使用此选项,如果不起作用,请尝试对日期字段(crr_ts)使用“between”。