我需要重新编写此代码而不使用子查询和显式联接。.help,请找一会儿
SELECT snum, pnum, shipdate
FROM supply as b
WHERE EXISTS (SELECT pname, pnum FROM parts as a WHERE b.pnum = a.pnum);
答案 0 :(得分:1)
我相信您已经收到了一个棘手的问题。答案是这样。
SELECT snum, pnum, shipdate
FROM supply
原因是,在设计良好的数据库中,您要检查的 条件应该是不可能的 。
让我们看看原始查询在做什么。
SELECT snum, pnum, shipdate
FROM supply as b
WHERE EXISTS (
SELECT pname, pnum FROM parts as a WHERE b.pnum = a.pnum
);
supply
中的每一行都在parts
中有对应的部分。在没有联接的查询中如何做到这一点?您不必一开始就这样做。相反,您应该依靠 referential integrity 。
引用完整性是表设计良好的属性,它表示 所有引用都是有效的 。无需检查supply
中的每个部分是否在parts
中存在,因为这样的条件应该是不可能的。您可以使用精心设计的架构来做到这一点,并适当使用外键和not null
约束。
(我的示例在Postgres中完成。您数据库的语法可能有所不同。)
create table parts(
pnum integer primary key,
pname text not null
);
create table supply(
snum integer primary key,
pnum integer references parts(pnum) not null,
shipdate date not null
);
通过将supply.pnum
声明为references parts(pnum)
,我们已经告诉数据库这是一个外键,并且{strong> 必须 1}}。添加parts
可以保证not null
中的每一行都必须提供有效的部分。数据库自动执行这些约束。
(请注意,MySQL takes a little more convincing会强制使用外键约束。因为MySQL是非标准的,所以它会养成学习它的不良习惯。请改用Postgres或SQLite。)
您还可以使用supply
将约束添加到现有表中。
alter table
例如,假设我们有这些部分。
test=> alter table supply alter pnum set not null;
ALTER TABLE
test=> alter table supply add constraint pnum_fk foreign key (pnum) references parts(pnum);
ALTER TABLE
我们可以在其中一个零件的供应中插入一行。
test=> select * from parts;
pnum | pname
------+---------
1 | flange
2 | thingy
3 | whatsit
但是,如果我们尝试插入不存在的部分,则会收到错误消息。
test=> insert into supply (pnum, shipdate) values (3, '2018-02-03');
INSERT 0 1
或者零件号为空的一个...
test=> insert into supply (pnum, shipdate) values (99, '2018-02-03');
ERROR: insert or update on table "supply" violates foreign key constraint "supply_pnum_fkey"
DETAIL: Key (pnum)=(99) is not present in table "parts".
您现在无法测试的条件。没必要。答案是:
test=> insert into supply (pnum, shipdate) values (null, '2018-02-03');
ERROR: null value in column "pnum" violates not-null constraint
DETAIL: Failing row contains (1, null, 2018-02-03).
答案 1 :(得分:0)
一种方法是if let randomIndex = deck.indices.randomElement() {
let newCard = deck.remove(at: randomIndex)
dealtCards.append(newCard)
} else {
// Deck is empty.
}
(列列表仅限于普通列表):
INTERSECT
使用SEMIJOIN
:
SELECT pnum
FROM supply
INTERSECT
SELECT pnum
FROM parts;
答案 2 :(得分:0)
子查询可以由INNER JOIN替换,如下所示:
SELECT b.snum, b.pnum, b.shipdate
FROM
supply as b
INNER JOIN parts as a ON b.pnum = a.pnum
GROUP BY b.snum, b.pnum, b.shipdate
您也可以进行隐式连接,但是我不建议您这样做,因为它的可读性和到目前为止都不受欢迎:
SELECT b.snum, b.pnum, b.shipdate
FROM
supply as b,
parts as a
WHERE b.pnum = a.pnum
GROUP BY b.snum, b.pnum, b.shipdate