gpt4 book ai didi

sql - 如何在没有循环/游标的情况下组合两个表来分配销售量与需求

转载 作者:行者123 更新时间:2023-12-04 02:16:37 26 4
gpt4 key购买 nike

我的任务是以特定方式组合两个表。我有一个包含某些商品 (tovar) 需求的表 Demands。每条记录都有自己的 ID、Tovar、需求日期和金额。我还有另一个表 Unloads,其中包含 tovar 的卸载。每条记录都有自己的 ID、Tovar、卸载顺序和金额。 DemandsUnloads 彼此不对应,需求量和卸载量不完全相等。一个需求可能有 10 个单位,并且可以有两个卸载 4 和 6 个单位。并且可以有3个和5个单位的两个需求,11个单位可以有一个卸载。

任务是获取一个表格,该表格将显示卸载量如何覆盖需求。我有一个解决方案 ( SQL Fiddle ),但我认为还有更好的解决方案。谁能告诉我这些任务是如何解决的?

我有什么:

------------------------------------------
| DemandNumber | Tovar | Amount | Order |
|--------------------------------|--------
| Demand#1 | Meat | 2 | 1 |
| Demand#2 | Meat | 3 | 2 |
| Demand#3 | Milk | 6 | 1 |
| Demand#4 | Eggs | 1 | 1 |
| Demand#5 | Eggs | 5 | 2 |
| Demand#6 | Eggs | 3 | 3 |
------------------------------------------

------------------------------------------
| SaleNumber | Tovar | Amount | Order |
|--------------------------------|--------
| Sale#1 | Meat | 6 | 1 |
| Sale#2 | Milk | 2 | 1 |
| Sale#3 | Milk | 1 | 2 |
| Sale#4 | Eggs | 2 | 1 |
| Sale#5 | Eggs | 1 | 2 |
| Sale#6 | Eggs | 4 | 3 |
------------------------------------------

我想收到什么

-------------------------------------------------
| DemandNumber | SaleNumber | Tovar | Amount |
-------------------------------------------------
| Demand#1 | Sale#1 | Meat | 2 |
| Demand#2 | Sale#1 | Meat | 3 |
| Demand#3 | Sale#2 | Milk | 2 |
| Demand#3 | Sale#3 | Milk | 1 |
| Demand#4 | Sale#4 | Eggs | 1 |
| Demand#5 | Sale#4 | Eggs | 1 |
| Demand#5 | Sale#5 | Eggs | 1 |
| Demand#5 | Sale#6 | Eggs | 3 |
| Demand#6 | Sale#6 | Eggs | 1 |
-------------------------------------------------

这里是作者评论的补充说明:

  • 需求#1 需要 2 block 肉,它可以从销售#1 中拿走它们。
  • 需求#2 需要 3 block 肉,可以从销售#1 中拿走。
  • 需求#3 需要 6 牛奶,但销售#3 中只有 2 牛奶,销售#4 中只有 1 牛奶,因此我们仅显示可用数量。
  • 等等。

示例中的字段Order 决定了计算的顺序。我们必须根据他们的订单处理需求。需求#1 必须在需求#2 之前处理。并且销售也必须根据他们的订单号进行分配。如果销售订单较低的鸡蛋和未分配的鸡蛋,我们不能分配销售的鸡蛋。


我能得到这个的唯一方法是使用循环。是否可以避免循环并仅使用 t-sql 解决此任务?

最佳答案

如果 Amount 值是 int 并且不是太大(不是数百万),那么我会使用 table of numbers生成与每个 Amount 的值一样多的行。这里有个好article描述如何生成它。

然后很容易加入 DemandSale 并根据需要分组和求和。

否则,一个简单明了的游标(实际上是两个游标)将易于实现、易于理解并且具有 O(n) 的复杂性。如果 Amounts 很小,基于集合的变体可能比游标更快。如果 Amounts 很大,光标可能会更快。您需要使用实际数据来衡量性能。

这是一个使用数字表的查询。要了解其工作原理,请分别运行 CTE 中的每个查询并检查其输出。

SQLFiddle

WITH
CTE_Demands
AS
(
SELECT
D.DemandNumber
,D.Tovar
,ROW_NUMBER() OVER (PARTITION BY D.Tovar ORDER BY D.SortOrder, CA_D.Number) AS rn
FROM
Demands AS D
CROSS APPLY
(
SELECT TOP(D.Amount) Numbers.Number
FROM Numbers
ORDER BY Numbers.Number
) AS CA_D
)
,CTE_Sales
AS
(
SELECT
S.SaleNumber
,S.Tovar
,ROW_NUMBER() OVER (PARTITION BY S.Tovar ORDER BY S.SortOrder, CA_S.Number) AS rn
FROM
Sales AS S
CROSS APPLY
(
SELECT TOP(S.Amount) Numbers.Number
FROM Numbers
ORDER BY Numbers.Number
) AS CA_S
)
SELECT
CTE_Demands.DemandNumber
,CTE_Sales.SaleNumber
,CTE_Demands.Tovar
,COUNT(*) AS Amount
FROM
CTE_Demands
INNER JOIN CTE_Sales ON
CTE_Sales.Tovar = CTE_Demands.Tovar
AND CTE_Sales.rn = CTE_Demands.rn
GROUP BY
CTE_Demands.Tovar
,CTE_Demands.DemandNumber
,CTE_Sales.SaleNumber
ORDER BY
CTE_Demands.DemandNumber
,CTE_Sales.SaleNumber
;

综上所述,通常最好使用过程编程语言在客户端执行此类处理。您仍然需要将 DemandsSales 中的所有行传输到客户端。因此,通过连接服务器上的表,您不会减少必须通过网络传输的字节数。事实上,你增加了它,因为原始行可能被分成几行。

这种处理本质上是顺序的,而不是基于集合的,所以用数组很容易做,但在 SQL 中很棘手。

关于sql - 如何在没有循环/游标的情况下组合两个表来分配销售量与需求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33377023/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com