在 GROUP BY 分组中,select 值基于另一列的最大值

Within GROUP BY grouping, select value based on highest value of another column

我正在尝试构建一个查询,将 GROUP BY 组缩减为单行,包括基于另一列最大值的列值。在这种情况下,我想要一个商品 ID、订购的总数量和最常用的供应商。

我已经成功构建了一个查询,该查询按项目和供应商对订购的数量和组进行求和,得到:

| id | qty | supplier       |
|  1 | 20  | S&S Activewear |
|  1 | 10  | J&J Textiles   |
|  2 | 5   | AB Footwear    |
|  2 | 10  | CD Shoes       |

预期结果将是订购的总数量(针对所有供应商)和最常用的供应商,因此:

| id | total_qty | most_used_supplier |
|  1 | 30        | S&S Activewear     |
|  2 | 15        | CD Shoes           |

从概念上讲,我想象做一个子查询,单独按 id 对上述结果进行分组,然后求和(数量)并通过按数量对 GROUP BY 进行排名以某种方式选择供应商值。

我已经阅读了很多相关的帖子,但是我没有成功地应用任何这些方法来达到这个目的,包括使用 ROW_NUMBER 和 PARTITION_BY。

我正在 Elixir 中使用 Ecto 在 Postgres 数据库上执行此操作,但为了使其通用化以便任何人都可以响应,我只是想了解如何在 SQL 中完成此操作。如果我可以提供更多详细信息,请告诉我,谢谢。

我将建议多个子查询:

select id, sum(qty),
       (select t2.supplier
        from t t2
        where t2.id = t.id
        order by t2.qty desc
        fetch first 1 row only
       ) as supplier
from t
group by id;

这使用标准语法返回一行。您的数据库可能有另一种相当于 fetch first 1 row only.

的语法

首先找出每个 id 的最大数量。 然后找到提供最大数量的合适供应商。如果超过一个"biggest",这里可能会出现问题,您必须看看如何处理它。 最后,再次加入相同的 table,添加适当的数量总和。

SELECT item.id, sum(item.qty) total_qty, biggestSupplier.supplier most_used_supplier
from item join
(
    SELECT item.id, supplier       
    from item
    JOIN 
    (
        SELECT id, max(qty) maxqty
        FROM item
        GROUP BY id
    ) maxQtyForId ON item.id = maxQtyForId.id AND item.qty = maxQtyForId.maxqty
) biggestSupplier ON item.id = biggestSupplier.id
group by item.id, biggestSupplier.supplier       

有几种方法,听起来你已经玩过这个了:

with data as (
    select *,
        row_number() over (partition by id order by qty desc) as rn
    from T
)
select id, sum(qty) as total_qty,
    (select d2.supplier from data d2
        where s2.id = d.id and rn = 1) as most_used_supplier
from data d
group by id;

我将问题分成 2 个。首先,找到最大数量,然后将数量相加。最后,加入table获取答案。

SELECT T4.ID, T5.sumQty AS total_qty,T4.supplier AS most_used_supplier
FROM [Test].[dbo].[Test] AS T4 LEFT JOIN
(
    SELECT ID,SUM(QTY) as sumQty
    FROM [Test].[dbo].[Test]
    GROUP BY ID
)AS T5
ON T4.ID = T5.ID
WHERE supplier IN
(
    SELECT supplier 
    FROM [Test].[dbo].[Test] AS T1 LEFT JOIN
        (
          SELECT MAX(qty) AS maxQty, ID
          FROM [Test].[dbo].[Test] AS T
          GROUP BY id
        ) AS T2
    ON T1.ID = T2.ID
    AND T1.qty = T2.maxQty
    WHERE T2.ID IS NOT NULL
)