如何查找廠商 B 生產的所有產品(任何類型)的型號和價格
數據庫方案由四個表組成:
- 產品(製造商、型號、類型)
- PC(程式碼、型號、速度、記憶體、高畫質、光碟、價格)
- 筆記型電腦(程式碼、型號、速度、記憶體、高畫質、螢幕、價格)
- 列印機(程式碼、型號、顏色、類型、價格)
產品表包含有關製造商、型號和產品類型(、
PC
或Laptop
)Printer
的數據。假定產品表中的型號對於所有製造商和產品類型都是唯一的。PC表中的每台個人電腦都由唯一程式碼明確標識,並通過其型號(外鍵指Product表)、處理器速度(以 MHz 為單位)-速度列、RAM 容量(以 Mb 為單位)-ram進行額外的表徵, 硬碟驅動器容量 (Gb) – hd , CD-ROM 速度 (例如,
4x
) – cd , 及其價格。Laptop表與PC表類似,不同之處在於它包含的不是 CD-ROM 速度,而是螢幕尺寸(以英寸為單位)- screen。
對於列印機表中的每個列印機型號,指定其輸出類型(
y
彩色和n
單色)-顏色列、列印技術(Laser
、Jet
或Matrix
)-類型和價格。現在我提出的查詢:
SELECT PC.model, price FROM PC INNER JOIN Product ON PC.model = Product.model UNION SELECT Laptop.model, price FROM Laptop INNER JOIN Product ON Laptop.model = Product.model UNION SELECT printer.model, price FROM printer INNER JOIN Product ON printer.model = Product.model WHERE Product.maker='B'
結果應該是:
model price 1121 850.0000 1750 1200.0000
我正在做 SQL 練習,但無法獲得相同的結果。
在
UNION
/UNION ALL
查詢中,WHERE
子句過濾單個子SELECT
(緊接在其前面的子)而不是整個 UNIONed 集——因此,每個子選擇都可以有自己的WHERE
子句。(這與 eg 不同ORDER BY
,您只能指定一次,並且將應用於組合集。)因此,如果您想要來自三個類別表中的每一個的同一製造商 B 的產品,您需要為每個子選擇重複過濾器:
SELECT PC.model, price FROM PC INNER JOIN Product ON PC.model = Product.model **WHERE Product.maker='B'** UNION SELECT Laptop.model, price FROM Laptop INNER JOIN Product ON Laptop.model = Product.model **WHERE Product.maker='B'** UNION SELECT printer.model, price FROM printer INNER JOIN Product ON printer.model = Product.model WHERE Product.maker='B'
這可能看起來像冗餘編碼,它可能是,並且在這種情況下有一些方法可以消除冗餘 - 例如通過使用派生表:
SELECT derived.model, derived.price FROM ( SELECT model, price FROM PC UNION SELECT model, price FROM Laptop UNION SELECT model, price FROM printer ) AS derived INNER JOIN Product ON derived.model = Product.model WHERE Product.maker='B' ;
但是在 SQL 中,DRY原則並不像在其他語言中那樣經常適用,這意味著重複在 SQL 中並不總是壞事,而消除重複並不總是好事。理論上,上面的兩個查詢應該是等價的。然而,在實踐中,並不是每個查詢優化器都可能認識到這一點,並且第二個查詢可能會導致執行計劃效率較低。
簡而言之,在一個查詢中多次重複一個條件在 SQL 中並不少見。有時重複變得太多,為了幫助查詢的可維護性,您可能希望使用視圖或儲存常式。但在這種情況下,重新訪問您的架構通常也會產生更好的影響。
WITH CTE AS ( SELECT model, price from PC UNION ALL SELECT model, price from Printer UNION ALL SELECT model, price from Laptop ) SELECT distinct C.model, C.price FROM CTE as C INNER JOIN Product as P ON C.model = P.model WHERE P.maker = 'B';