【问题标题】:Finding the highest price from three different tables从三个不同的表中找到最高价格
【发布时间】:2015-03-06 23:05:15
【问题描述】:

我必须从三个不同的表中找到最高价格,但我现在不知道如何获得 P 的最大值。

PC(型号、速度、内存、高清、价格)

笔记本电脑(型号、速度、内存、高清、屏幕、价格)

打印机(型号、颜色、类型、价格)

SELECT model
FROM ((SELECT MAX(price)
      FROM PC)
      UNION
      (SELECT MAX(price)
      FROM Laptop)
      UNION
      (SELECT MAX(price)
      FROM Printer)) AS P
WHERE MAX(P);

我可以在前面添加 MAX 吗?喜欢

SELECT model
FROM MAX((SELECT MAX(price)
     FROM PC)
     UNION
     (SELECT MAX(price)
     FROM Laptop)
     UNION
     (SELECT MAX(price)
     FROM Printer));

【问题讨论】:

  • 你试过了吗?您想从任一表中获取价格最高的记录,还是只获取价格最高的记录?
  • 您使用的是哪个 DBMS?后格雷斯?甲骨文?
  • 请参阅"Should questions include “tags” in their titles?",其中的共识是“不,他们不应该”!

标签: sql max


【解决方案1】:

如果您想要模型,请使用union allorder by。你不指定数据库,所以这里是ANSI标准解决方案:

SELECT model, price
FROM ((SELECT model, price FROM PC)
      UNION ALL
      (SELECT model, price FROM Laptop)
      UNION ALL
      (SELECT model, price FROM printer)
     ) p
ORDER BY price desc
FETCH FIRST 1 ROW ONLY;

数据库之间真正不同的唯一部分是FETCH FIRST 1 ROW ONLY。这可能是limittop 或其他一些构造。

【讨论】:

    【解决方案2】:

    首先,您应该为每个表找到max(price)。在这种情况下,查询将计算所有使用索引(假设您有一个价格)。

    UPD:此外,您最好对表格进行规范化并将价格(和其他常见字段)提取到单独的表格中。这将允许您使用此表进行价格操纵并处理您的实体而不关心它们的具体类型。

    【讨论】:

      【解决方案3】:

      如果您只想获得 1 条价格最高的记录,您应该使用 TOP 1。类似的东西:

      SELECT TOP 1 model
      FROM ((SELECT MAX(price)
             FROM PC)
            UNION
            (SELECT MAX(price)
             FROM Laptop)
            UNION
            (SELECT MAX(price)
             FROM Printer)) AS P
      WHERE MAX(P)
      ORDER BY P DESC;
      

      【讨论】:

      • 这样你得到这三个中的第一个价格,不一定是最高的。
      • WHERE 子句中真的可以有聚合函数吗?目的是什么?
      【解决方案4】:

      注意:您尚未指定供应商,我将使用 Oracle 文档作为答案(但它可能是可移植的)。

      您只需要最高的价格吗?那么现在子查询就足够了,但是你错误地使用了聚合函数:

      SELECT
        MAX(PRICE) AS HIGHEST_FROM_ALL_TABLES
      FROM
        (
          SELECT MAX(PRICE) AS PRICE FROM PC
          UNION
          SELECT MAX(PRICE) AS PRICE FROM LAPTOP
          UNION
          SELECT MAX(PRICE) AS PRICE FROM PRINTER
        )
      

      但是,如果您还需要模型,则需要稍微不同的方法。

      SELECT
        MAX(PRICE) KEEP(DENSE_RANK LAST ORDER BY PRICE) AS HIGHEST_PRICE,
        MAX(MODEL) KEEP(DENSE_RANK LAST ORDER BY PRICE) AS THE_MODEL
      FROM
        (
          SELECT PRICE, MODEL FROM PC
          UNION ALL
          SELECT PRICE, MODEL FROM LAPTOP
          UNION ALL
          SELECT PRICE, MODEL FROM PRINTER
        )
      

      在这里,我们:

      1. 将幸运地具有相同列布局的三个表合并。
      2. 使用LAST解析函数没有分区,最后只能得到一行。 (mssql翻译:here

      结果是全局最高价格及其相关模型。如果您有多行价格相同,它仍然只返回一个,即订单经过的最后一个。

      最好的方法是获取所需行的 ID,并将此分析选择作为子查询。然后获取唯一具有此 ID 的行。

      【讨论】:

        【解决方案5】:

        如果您在子查询中使用 MAX,您可以:

        SELECT model FROM (
            (SELECT model, price FROM PC)
            union
            (SELECT model, price FROM Laptop)
            union
            (SELECT model, price FROM Printer)
        ) as AllPrices
        WHERE price = (
            select max(val) from (
                (SELECT max(price) as val FROM PC)
                union
                (SELECT max(price) as val FROM Laptop)
                union
                (SELECT max(price) as val FROM Printer)
            ) as MaxPrices
        )
        LIMIT 1
        

        这更大,但实际上比简单地选择整个表和排序更快,因为它为数据库引擎提供了更好的优化机会(它不需要对所有记录进行排序,只需要对重要的记录进行排序)。在 Postgresql 上测试,它在一个非常大的数据库上运行时间只有一半。

        【讨论】:

          猜你喜欢
          • 2018-11-08
          • 2011-06-16
          • 1970-01-01
          • 2019-06-13
          • 2013-04-20
          • 2021-06-27
          • 2012-06-07
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多