【问题标题】:How to emulate window functions in MySQL < 8.0如何在 MySQL < 8.0 中模拟窗口函数
【发布时间】:2019-11-24 14:53:34
【问题描述】:

我有这样的表格:

INSERT INTO listings 
(id, external_id, variation_id, product_id) VALUES
(101, '9900001', '9900001var1', 1),
(102, '9900001', '9900001var2', 4),
(103, '9900002', '9900002var1', 1),
(104, '9900002', '9900002var2', 2),
(105, '9900003', '9900003var1', 3),
(106, '9900003', '9900003var2', 4);

INSERT INTO products
(id, price) VALUES
(1, 101),
(2, 100),
(3, 100),
(4, 102);

这意味着有 3 个列表(9900001、9900002、9900003),每个列表分别包含 2 个产品(1、4)、(1、2)和(3、4)。

我需要为每个列表检索一行,其中包含该列表中价格最高的产品的 ID(不是价格)。

因此,所需的输出将是:

id    | external_id | variation_id | product_id
[ANY]   9900001       [ANY]          4
[ANY]   9900002       [ANY]          1
[ANY]   9900003       [ANY]          4

我得到的最接近所需答案的是这个查询:

SELECT
    p.id AS product_id_max,
    p.price AS product_price_max,
    MAX(p.price) AS product_price_max_max,
    listings.* 
            FROM listings
            INNER JOIN (

              -- Subquery tested above:
              SELECT DISTINCT pp3.* FROM 
                (SELECT MAX(p2.price) as max_price
                FROM products p2
                INNER JOIN listings l2 ON l2.product_id = p2.id 
                GROUP BY l2.external_id) pp2
              INNER JOIN
                (SELECT p3.* FROM products p3 ) pp3
              ON
                pp2.max_price = pp3.price
              ORDER BY pp3.price DESC

            ) AS p
            ON p.id = listings.product_id
            -- WHERE MAX(p.price) = p.price
            GROUP BY external_id
            -- HAVING MAX(p.price) = p.price
            ORDER BY product_price_max DESC

取消注释 WHERE 子句会引发错误,取消注释 HAVING 子句返回的行数少于所需的行数。 Levin 都评论说在 product_id 列中给出了正确的行但错误的值。

小提琴:http://sqlfiddle.com/#!9/d58d665/54/0

【问题讨论】:

  • @bill-karwin 您发布的链接回答了不同的问题。听起来相似,但问题不同。
  • 好的,我把重复问题的链接倒过来了。我会留下greatest-n-per-group 标签,因为它属于一般类型的问题。
  • 自从 MySQL 8.0 增加了窗口函数,每组最大 n 的每个问题都应该包括 MySQL 的版本。如果你可以使用 MySQL 8.0+,你应该使用窗口函数。
  • 哇!窗口函数是我一直在寻找的答案!我使用 MariaDB 10.1.22,但我想我可以升级到 10.2,如果他们添加了对这些的支持。谢谢!
  • 我将很快编辑这个问题以反映这里真正取得的成就。现在我改变了标题。

标签: mariadb greatest-n-per-group


【解决方案1】:

我想通了:

SELECT
    listings.*,
    max_p.product_id AS max_product_id
            FROM listings
            INNER JOIN (

              SELECT DISTINCT max_external_id as external_id, pp3.id as product_id FROM
                (SELECT MAX(p2.price) as max_price, l2.external_id as max_external_id
                FROM products p2
                INNER JOIN listings l2 ON l2.product_id = p2.id
                GROUP BY l2.external_id) pp2
              INNER JOIN
                (SELECT p3.* FROM products p3 ) pp3
              ON
                pp2.max_price = pp3.price
              ORDER BY pp3.price DESC

            ) AS max_p
            ON max_p.external_id = listings.external_id
            GROUP BY listings.external_id

在这里测试:

http://sqlfiddle.com/#!9/d58d665/53/0

【讨论】:

    猜你喜欢
    • 2015-08-18
    • 1970-01-01
    • 2012-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-24
    • 1970-01-01
    • 2023-03-08
    相关资源
    最近更新 更多