Query

如何查找廠商 B 生產的所有產品(任何類型)的型號和價格

  • November 1, 2018

數據庫方案由四個表組成:

  • 產品製造商、型號、類型
  • PC程式碼、型號、速度、記憶體、高畫質、光碟、價格
  • 筆記型電腦程式碼、型號、速度、記憶體、高畫質、螢幕、價格
  • 列印機程式碼、型號、顏色、類型、價格

產品表包含有關製造商、型號和產品類型(、PCLaptopPrinter的數據。假定產品表中的型號對於所有製造商和產品類型都是唯一的。

PC表中的每台個人電腦都由唯一程式碼明確標識,並通過其型號(外鍵指Product表)、處理器速度(以 MHz 為單位)-速度列、RAM 容量(以 Mb 為單位)-ram進行額外的表徵, 硬碟驅動器容量 (Gb) – hd , CD-ROM 速度 (例如, 4x) – cd , 及其價格

Laptop表與PC表類似,不同之處在於它包含的不是 CD-ROM 速度,而是螢幕尺寸(以英寸為單位)- screen

對於列印機表中的每個列印機型號,指定其輸出類型(y彩色和n單色)-顏色列、列印技術(LaserJetMatrix)-類型價格

現在我提出的查詢:

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';

引用自:https://dba.stackexchange.com/questions/134295