求至少用了供應商「S1」所供應的全部零件的工程號 的兩種解法

2020-10-02 01:00:11

"求至少用了供應商「S1」所供應的全部零件的工程號"的兩種解法

1. 題設

資料庫SPJ包含4個表:

供應商表S(程式碼Sno,名稱Sname,狀態Status,所在城市City)

SnoSnameStatusCity

零件表P(程式碼Pno,名稱Pname,顏色Color,重量Weight)

PnoPnameColorWeight

工程專案表J(程式碼Jno,名稱Jname,所在城市City)

JnoJnameCity

供應情況表Spj(供應商程式碼Sno,零件程式碼Pno,專案程式碼Jno,數量Qty)

SnoPnoJnoQty

問題是:至少使用了工程S1供應的全部零件的工程號JNO

2. 方法一:直接求解

思路:直接求解,首先找出S1供應商供應的全部零件集合P1,再對每一個工程找出其使用的零件集合Pn,如果P1⊆Pn,則說明該工程使用了S1供應商供應的全部零件。

(select b.Pno from Spj as b where b.Sno='S1') as d //S1供應商供應的全部零件集合P1
(select c.Pno from Spj as c where c.Jno='某一工程代號') //某一工程使用的零件集合

要判斷P1⊆Pn的真假,只要求P1和Pn的差集,即P1-Pn,若P1-Pn為空集(查詢結果不存在),則說明P1⊆Pn。
注:在Mysql中select * from A where * not in B;可以用來求A-B的差集。

select * from
(select b.Pno from Spj as b where b.Sno='S1') as d
where d.Pno not in
(select c.Pno from Spj as c where c.Jno='某一工程代號')
//若查詢返回結果為空,則說明該工程沒有使用所有的S1提供的零件。

之後再使用not exists來判斷某一工程是否符合條件,再用a.Jno代替'某一工程代號'的佔位來遍歷J表中每一個工程。

select Jno from J as a where not exists(
select * from
(select b.Pno from Spj as b where b.Sno='S1') as d
where d.Pno not in
(select c.Pno from Spj as c where c.Jno=a.Jno)
);

3. 方法二:間接求解

很多部落格都寫了,因此不再贅述。
Alt