它说我没有选择行?
Posted
技术标签:
【中文标题】它说我没有选择行?【英文标题】:Its saying I have no row selected? 【发布时间】:2017-09-23 13:36:39 【问题描述】:这表示我没有选择任何行。
这是一个问题: 查找过去或现在从未借过书的会员的会员 ID、姓氏和名字。
这是架构,主键是粗体。
图书(bookID、ISBN、书名、作者、出版年份、类别)
会员(memberID、姓、名、地址、电话号码、限制)
CurrentLoan(memberID, bookID, loan-date, due-date)
历史记录(memberID、bookID、借出日期、归还日期)
会员可以从图书馆借书。他们可以借书的数量受成员关系的“限制”字段的限制(不同的成员可能会有所不同)。书籍的类别包括小说、非小说、儿童和参考书。 CurrentLoan 表表示有关当前已签出的书籍的信息。当图书归还图书馆时,该记录将从 CurrentLoad 关系中删除,并以归还日期插入到 History 关系中。一个图书馆可能拥有同一本书的多个副本,在这种情况下,每个副本都有自己的 bookID,但所有副本共享相同的 ISBN。
这是我的代码:
CREATE TABLE Book
(bookID INT,
ISBN INT,
title varchar (25),
author varchar (20),
publish_year INT,
category varchar(20),
PRIMARY KEY (bookID));
CREATE TABLE Member
(memberID INT,
lastname varchar (20),
firstname varchar (20),
address varchar(20),
phone_number INT,
limit_ INT,
PRIMARY KEY (memberID));
CREATE TABLE CurrentLoan
(memberID INT ,
bookID INT,
loan_date DATE,
due_date DATE,
PRIMARY KEY (memberID, bookID),
FOREIGN KEY (memberID) REFERENCES Member(memberID),
FOREIGN KEY (bookID) REFERENCES Book(bookID));
CREATE TABLE History
(memberID INT,
bookID INT,
loan_date DATE,
return_date DATE,
PRIMARY KEY (memberID, bookID, loan_date),
FOREIGN KEY (memberID) REFERENCES Member(memberID),
FOREIGN KEY (bookID) REFERENCES Book(bookID));
INSERT INTO Book VALUES (10, 1113312336, 'The Dog', 'Jack Crow', 1990, 'fiction');
INSERT INTO Book VALUES (12, 2221254896, 'Worms', 'Jim Kan', 2013, 'childrens');
INSERT INTO Book VALUES (13, 3332546987, 'Crow', 'Jan Flo', 2000, 'fiction');
INSERT INTO Book VALUES (14, 4443456215, 'Big Dog', 'Lan Big', 1993, 'children');
INSERT INTO Book VALUES (15, 5552314569, 'Green Apple', 'Theo Brown', 1978, 'children');
INSERT INTO Book VALUES (16, 6664581631, 'Red Bean', 'Khang Nk', 2017, 'fiction');
INSERT INTO Book VALUES (17, 7771452369, 'XML and XQuery Knowledge', 'Author Le', 2017, 'non-fiction');
INSERT INTO Book VALUES (18, 8881245525, 'The Dark Room', 'Jack Se', 2017, 'fiction');
INSERT INTO Book VALUES (19, 9991123546, 'Lonely Mens', 'Geen Brown', 2014, 'refrence');
INSERT INTO Book VALUES (20, 1122112356, 'XML or XQuery', 'Heart Le', 2002, 'fiction');
INSERT INTO Member VALUES (001, 'Lee', 'Nancy', 'Brownlea Drive', 1254896325, 2);
INSERT INTO Member VALUES (002, 'Le', 'Ray', '10th Street', 1234561256, 2);
INSERT INTO Member VALUES (003, 'Kan', 'Charlie', '5th Street', 1234567236, 2);
INSERT INTO Member VALUES (004, 'Brown', 'Joe', 'Elm Street', 1234567845, 2);
INSERT INTO Member VALUES (005, 'Smith', 'John', '33 East', 1234567890, 2);
INSERT INTO CurrentLoan VALUES (005, 10, '13-SEP-17', '14-NOV-17');
INSERT INTO CurrentLoan VALUES (005, 19, '13-JAN-17', '15-NOV-17');
INSERT INTO CurrentLoan VALUES (003, 16, '14-FEB-17', '12-MAR-17');
INSERT INTO CurrentLoan VALUES (004, 15, '12-OCT-17', '09-NOV-17');
INSERT INTO CurrentLoan VALUES (005, 18, '13-APR-17', '12-MAY-17');
INSERT INTO History VALUES (001, 10, '14-Jan-17', '04-OCT-17');
INSERT INTO History VALUES (002, 19, '12-Jan-17', '04-NOV-17');
INSERT INTO History VALUES (003, 13, '14-APR-17', '08-OCT-17');
INSERT INTO History VALUES (005, 20, '14-MAY-17', '04-DEC-17');
我的查询是:
SELECT Member.memberID, lastname, firstname
FROM Member MINUS(
SELECT Member.memberID, lastname, firstname
FROM Member, CurrentLoan
WHERE Member.memberID = CurrentLoan.memberID
UNION
SELECT Member.memberID, lastname, firstname
FROM Member, History
WHERE Member.memberID = History.memberID);
【问题讨论】:
您使用的是 mysql 还是 Oracle?为什么在FROM
子句中使用逗号。那是古老的语法。使用正确、明确的JOIN
语法。
您正在减去 MINUS
语句的谓词中的所有五个 Member
记录。完全期望一个空的结果集。
@GordonLinoff 抱歉,我正在使用 Oracle
Tim 说的:您的数据中只有五个成员,ID 从 01 到 05。01、02 和 03 出现在历史记录表中。 03、04 和 05 出现在当前表中。所以没有任何成员在过去或现在从未有过贷款。 “没有返回行”是正确答案。这种情况在现实生活中也经常发生,不仅仅是在家庭作业中,我很高兴看到家庭作业能尽早教你这些东西。这是很好的功课!
为什么对这个问题投反对票?它被完美地问到:这里有创建表和插入数据的语句;这是我的查询、我得到的结果以及我不明白的地方。 如果有的话,这是应该如何提问的模型。
【参考方案1】:
有几种方法可以做到这一点:
可以使用反连接,如:
SELECT m.MEMBERID,
m.LASTNAME,
m.FIRSTNAME
FROM MEMBERS m
WHERE m.MEMBERID NOT IN (SELECT DISTINCT MEMBERID
FROM CURRENTLOAN
UNION ALL
SELECT DISTINCT MEMBERID
FROM HISTORY);
做你想做的另一种方法(也是我喜欢的方法)是:
SELECT DISTINCT m.MEMBERID,
m.LASTNAME,
m.FIRSTNAME
FROM MEMBERS m
LEFT OUTER JOIN (SELECT DISTINCT MEMBERID
FROM (SELECT MEMBERID
FROM CURRENTLOAN
UNION ALL
SELECT MEMBERID
FROM HISTORY)) u
ON u.MEMBERID = m.MEMBERID
WHERE u.MEMBERID IS NULL;
但是,鉴于您显示此查询的数据以及您的原始查询,应该返回零行。 SQLFiddle here
请注意,如果您注释掉当前对成员 004 的贷款,则返回“Joe Brown”SQLFiddle here
祝你好运。
【讨论】:
这将有助于理解为什么您更喜欢外连接而不是反连接。人们会期望(有些人会声称他们可以证明)Oracle 优化了反连接,因此它们比更一般的左外连接工作得更快。 (从逻辑上讲,这很明显——平均而言,反连接只需要检查“右侧表”中一半的行以查找将被拒绝的行。标准连接将始终检查右侧的所有行——边桌。) @mathguy:很有趣。如果您愿意花时间回答this question,我会很感兴趣。谢谢。 至于“为什么我更喜欢带有过滤器的左外连接而不是反连接”-我想这可能是我定期使用 Rdb 时的遗留问题,在我的 11-岁的回忆反加入普遍缓慢。旧习难改。 :-) 我也会编辑和添加反连接方法。 幸运的是我没有忘记旧习惯(我开始学习 SQL - 真的只有 Oracle,我知道的唯一方言);但是从我所读到的,至少在 Oracle 8 之前,与常规连接相比,反连接确实很慢。但那是很久以前的事了。 Oracle 做错了一些事情,但它确实做对了很多事情,而且它们不会停滞不前。以上是关于它说我没有选择行?的主要内容,如果未能解决你的问题,请参考以下文章