如何在MySQL <8.0中模拟窗口函数

时间:2019-07-15 21:51:03

标签: mariadb greatest-n-per-group

我有这样的表:

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),每个商品分别有(1、4),(1、2)和(3、4)2种商品。

我需要为每个列表检索一行,并使用该列表中价格最高的产品的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子句返回的行少于所需的行。 Leavin都评论说给了正确的行,但product_id列中的值不正确。

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

1 个答案:

答案 0 :(得分:0)

我知道了:

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