在GROUP BY分组中,根据另一列的最大值选择值

时间:2019-08-28 17:33:38

标签: sql elixir ecto

我正在尝试建立一个查询,以将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分组,然后按sum(qty)分组,然后通过按数量对GROUP BY排序,以某种方式选择供应商的价值。

我已经阅读了许多相关的文章,但是我未能成功地将所有这些方法应用于此目的,包括使用ROW_NUMBER和PARTITION_BY。

我正在Elixir上与Postgres DB上的Ecto一起执行此操作,但是为了使其泛化,以便任何人都可以响应,我只是想了解如何在SQL中完成此操作。请让我知道是否能提供更多详细信息,谢谢。

4 个答案:

答案 0 :(得分:0)

我将建议多个子查询:

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等效的另一种语法。

答案 1 :(得分:0)

首先为每个ID找到最大数量。 然后找到提供最大数量的合适供应商。如果存在多个“最大”问题,则可能会出现此问题,您必须查看如何处理它。 最后,只需将其再次连接到同一张表,并添加适当的数量总和即可。

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       

答案 2 :(得分:0)

有几种方法,听起来您甚至都玩过这种方法:

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;

答案 3 :(得分:0)

我将问题分成2个步骤。首先,找到最大数量,然后求和。最后,加入表格以获取答案。

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
)