数据库方案由四个表组成:
的产品表包含的制造者的数据,型号和产品的类型(PC
,Laptop
,或Printer
)。假设产品表中的型号对于所有制造商和产品类型都是唯一的。
PC表中的每台个人计算机都由唯一代码明确标识,并另外通过其型号(外键指产品表)、处理器速度(以 MHz 为单位)-速度列、RAM 容量(以 Mb 为单位)- ram 进行表征、硬盘驱动器容量(以 Gb 为单位)- hd、CD-ROM 速度(例如4x
)- cd及其价格。
该笔记本电脑桌类似于PC表,只是代替了CD-ROM的速度,它包含的屏幕尺寸(英寸) -屏幕。
对于打印机表中的每个打印机型号,指定了其输出类型(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'
Run Code Online (Sandbox Code Playgroud)
结果应该是:
model price
1121 850.0000
1750 1200.0000
Run Code Online (Sandbox Code Playgroud)
我正在做 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'
Run Code Online (Sandbox Code Playgroud)
这可能看起来像冗余编码,它可能是,并且在这种情况下有一些方法可以消除冗余 - 例如通过使用派生表:
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'
;
Run Code Online (Sandbox Code Playgroud)
但是在 SQL 中,DRY原则不像在其他语言中那样经常应用,这意味着在 SQL 中重复并不总是坏事,消除重复并不总是好的。理论上,上面的两个查询应该是等价的。然而,在实践中,并非每个查询优化器都可能认识到这一点,第二个查询可能会导致执行计划效率较低。
简而言之,在单个查询中多次重复一个条件在 SQL 中并不少见。有时重复变得太多,为了帮助查询的可维护性,您可能需要使用视图或存储例程。但在这种情况下,重新访问您的架构通常会产生更好的影响。