SQL select 列中具有最大值的 JOIN 行

SQL select rows in a JOIN with max value on a column

我正在从 3 个不同的 table 中选择值以获取一些产品订单的概览。 没有 MAX,没有问题。

这是我正在处理的数据:

-- limited to first rows for the sake of the exemple
+------+---------------------+-------------------------------+-------+
| ID   | post_date           | order_item_name               | price |
+------+---------------------+-------------------------------+-------+
| 2348 | 2019-01-23 18:47:34 | product A                     | 18.9  |
| 2348 | 2019-01-23 18:47:34 | Product B                     | 4.5   |
| 2348 | 2019-01-23 18:47:34 | Product C                     | 50.5  |
| 2349 | 2019-01-23 21:59:04 | Product E                     | 26.5  |
| 2352 | 2019-01-24 07:41:12 | Product C                     | 50.5  |
+------+---------------------+-------------------------------+-------+

这些由以下 SQL 查询返回。

SELECT 
    p.ID AS order_id,
    post_date,
    order_item_name,
    meta_value as price
FROM wp_posts AS p
JOIN wp_woocommerce_order_items
ON p.ID = order_id
JOIN wp_woocommerce_order_itemmeta
ON wp_woocommerce_order_items.order_item_id = wp_woocommerce_order_itemmeta.order_item_id
WHERE 
    post_type = 'shop_order' 
    AND post_status = 'wc-completed'
    AND meta_key = '_line_subtotal';

现在我想要的是只从每个订单中获取最昂贵的产品。 很明显,只是使用 MAX 函数和 GROUP BY returns 每个订单一行,但是产品名称与价格不匹配。

SELECT 
    p.ID AS order_id,
    post_date,
    order_item_name,
    MAX(meta_value) AS price
FROM alpha_posts AS p
JOIN alpha_woocommerce_order_items
ON p.ID = order_id
JOIN alpha_woocommerce_order_itemmeta
ON alpha_woocommerce_order_items.order_item_id = alpha_woocommerce_order_itemmeta.order_item_id
WHERE 
    post_type = 'shop_order' 
    AND post_status = 'wc-completed'
    AND meta_key = '_line_subtotal'
GROUP BY order_id;

returns 最高价,但 order_item_name 列与给定价格不对应。

+----------+---------------------+-------------------------------+-------+
| order_id | post_date           | order_item_name               | price |
+----------+---------------------+-------------------------------+-------+
|     2348 | 2019-01-23 18:47:34 | Product A                     | 50.5  | -- should be product C
|     2349 | 2019-01-23 21:59:04 | Product B                     | 26.5  | -- product b is 4.5, so it's clearly not matching (same for the following results)
|     2352 | 2019-01-24 07:41:12 | Product A                     | 60.9  |
|     2354 | 2019-01-25 07:43:36 | Product C                     | 23.1  |
|     2355 | 2019-01-26 19:59:31 | Product D                     | 79.9  |
+----------+---------------------+-------------------------------+-------+

我已经设法找到了一个 table 查询的示例,但我对这个多连接查询无能为力。

您可以使用 row_number():

SELECT x.*
FROM (SELECT p.ID AS order_id, post_date, order_item_name, oimmeta_value as price,
             ROW_NUMBER() OVER (PARTITION BY p.ID ORDER BY (meta_value + 0) DESC) as seqnum
      FROM wp_posts p JOIN
           wp_woocommerce_order_items oi
           ON p.ID = oi.order_id JOIN
           wp_woocommerce_order_itemmeta oim
           ON oi.order_item_id = oim.order_item_id
      WHERE p.post_type = 'shop_order' AND
            p.post_status = 'wc-completed' AND
            wpm.meta_key = '_line_subtotal'
     ) x
WHERE seqnum = 1;

注意:这假定 meta_value 是一个字符串,因此需要将其转换为数字以进行排序。

正如预期的那样,聚合函数只作用于一列而不考虑其他列,它们不是过滤器。

这就是为什么MAX函数returns指定列中满足最大值,而其他列不是对应最大值selected(或任何聚合函数的结果)。

为了 select 基于最大值的匹配列,我们可以使用 JOIN 查询,在我们的例子中,在 order_id 和 [=14= 上加入].

SELECT 
    ID, 
    post_date,
    wp_woocommerce_order_items.order_item_name,
    wp_woocommerce_order_itemmeta.meta_value
FROM wp_posts
JOIN wp_woocommerce_order_items
ON ID = order_id
JOIN wp_woocommerce_order_itemmeta
ON wp_woocommerce_order_items.order_item_id = wp_woocommerce_order_itemmeta.order_item_id
JOIN (
    SELECT
        order_id,
        MAX(meta_value) as price
    FROM wp_woocommerce_order_items
    JOIN wp_woocommerce_order_itemmeta
    ON wp_woocommerce_order_items.order_item_id = wp_woocommerce_order_itemmeta.order_item_id
    WHERE meta_key = '_line_subtotal'
    GROUP BY order_id
) b
ON ID = b.order_id AND wp_woocommerce_order_itemmeta.meta_value = price
WHERE 
    post_type = 'shop_order' 
    AND post_status = 'wc-completed'
    AND meta_key = '_line_subtotal';