我正在尝试建立一个查询,以将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中完成此操作。请让我知道是否能提供更多详细信息,谢谢。
答案 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
)