sql-server - 对于至少在台式电脑、笔记本电脑或打印机之一上拥有型号的每个制造商,确定其产品的最高价格。输出: maker;

标签 sql-server t-sql

任务:对于至少在台式电脑、笔记本电脑或打印机之一中拥有型号的每个制造商,确定其产品的最高价格。输出:制造者;如果给定制造商的产品价格中有 NULL 值,则显示该制造商的 NULL,否则显示最高价格。

这是来自此网站的任务 41:http://www.sql-ex.ru/

数据库说明:

数据库方案由四个表组成:

  • 产品(制造商、型号、类型)
  • PC(代码、型号、速度、内存、高清、CD、价格)
  • 笔记本电脑(代码、型号、速度、内存、高清、屏幕、价格)
  • 打印机(代码、型号、颜色、类型、价格)

Product 表包含有关制造商、型号和产品类型(“PC”、“笔记本电脑”或“打印机”)的数据。假设 Product 表中的型号对于所有制造商和产品类型都是唯一的。 PC 表中的每台个人计算机均由唯一代码明确标识,并且还具有型号(外键指的是产品表)、处理器速度(以 MHz 为单位)- 速度字段、RAM 容量(以 Mb 为单位)- ram 的特征、硬盘驱动器容量(以 Gb 为单位)- hd、CD-ROM 速度(例如“4x”)- cd 及其价格。

Laptop 表与 PC 表类似,不同之处在于它包含屏幕尺寸(以英寸为单位)而不是 CD-ROM 速度 - 屏幕。对于 Printer 表中的每个打印机型号,其输出类型(“y”表示彩色,“n”表示单色)- 色域、打印技术(“激光”、“喷射”或“矩阵”) ') – 指定类型和价格。

我尝试了几个查询,其中大多数在第一个数据库上有效,但在第二个数据库上无效

这是我最后一次尝试的查询:

SELECT DISTINCT 
    maker, 
    CASE 
       WHEN price IS NULL 
          THEN NULL 
          ELSE MAX(price) OVER (PARTITION by maker) 
    END max_p 
FROM 
    (SELECT DISTINCT maker, price 
     FROM product 
     LEFT JOIN pc ON pc.model = product.model
     WHERE product.model IN (SELECT model FROM pc)

     UNION 

     SELECT DISTINCT maker, price 
     FROM product 
     LEFT JOIN laptop ON laptop.model = product.model
     WHERE product.model IN (SELECT model FROM laptop)

     UNION

     SELECT DISTINCT maker, price FROM product 
     LEFT JOIN printer ON printer.model = product.model
     WHERE product.model IN (SELECT model FROM printer)) as x

您的查询在第一个(可用)数据库上返回了正确的数据集,但在第二个检查数据库上返回了错误的数据集。

  • 记录数错误(多了 3 个)

    enter image description here

最佳答案

每个制造商最昂贵的产品,如果任何制造商的价格为空,则为空:

SELECT
  pro.maker,
  NULLIF(MAX(COALESCE(pri.price, 922337203685477)), 922337203685477) as price
FROM
  product pro
  INNER JOIN
  (
    SELECT model, price FROM printer
    UNION ALL
    SELECT model, price FROM pc
    UNION ALL
    SELECT model, price FROM laptop
  ) pri 
  ON pri.model = pro.model
GROUP BY pro.maker

它是如何工作的:

将笔记本电脑、个人电脑和打印机表剥离出来,仅保留型号和价格(包括任何空价格),然后合并在一起以提供一致的数据集。将其加入到产品中即可获得制造商。按制造商分组寻找最高价格。因为我们必须将 null 显示为存在任何 null 价格的最高价格,所以我们合并使所有 null 价格成为一个非常高的价格,因此它们肯定是最高价格,然后我们使用 NULLIF< 将这个非常高的价格恢复为 null/p>

NULLIF 是专有的。我可以用 case when max(...) = 922... then null else max(...) end 做同样的事情 但它更啰嗦

琐事:

922337203685477 几乎是金钱的最大值;我省略了小数部分

另请考虑:

三个硬件表中的两个具有类型列。没有说明这是否与产品表的类型列有关。如果是,您必须将其添加到联接中。对于缺少类型的表,将其置空,并让连接条件包含“or pri.type is null”

关于sql-server - 对于至少在台式电脑、笔记本电脑或打印机之一上拥有型号的每个制造商,确定其产品的最高价格。输出: maker;,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57296784/

相关文章:

sql-server - 分层数据 - 递归 CTE 加 PIVOT?

t-sql - 查找并替换主字符串中的字符串

SQL 更新列以等于连接中的列并使用子查询

sql-server - 更改列,添加默认约束

SQL 查询变量与硬编码值

sql - 自连接查询以查找重复记录

t-sql - Unpivot SQL 事物

sql-server - 解释表数据中的主键

sql - 将 case 语句与 stuff 结合使用

sql - 将字符串拆分为 3 列 - 稍作改动