首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >SQL Server中的For循环-这是正确的逻辑吗?

SQL Server中的For循环-这是正确的逻辑吗?
EN

Stack Overflow用户
提问于 2012-06-12 00:44:43
回答 4查看 1.8K关注 0票数 0

我正在尝试获取事务数据并对其进行清理,以满足我的分析需求。在如何将事务记录到数据库方面存在一些限制,我正在尝试绕过这些限制。

当客户下订单时,事务数据库不会将多个产品链接在一起。每个产品都有一个唯一的销售ID,但无法将多个销售ID分组到一个订单中。下面是一个示例:

代码语言:javascript
运行
复制
OrderID   MultOrderID   CustomerID  SalesDate   SalesTime   ProductID   ProductCost ShippingCost
6082346                 7661X0A     2012-06-12  959         105         99.99       7.95
6082347   5809812YY6Y   T891002     2012-06-12  1005        222         99.95       7.95
6082348   5809812YY6Z   T891002     2012-06-12  1005        273         22.95       1.00
6082349   5809812YY71   T891002     2012-06-12  1005        285         499.95      1.00
6082350   5809812YY72   T891002     2012-06-12  1005        172         49.95       1.00
6082351   5809812YY73   T891002     2012-06-12  1005        105         99.99       7.95
6082352   5809812YY74   X637251     2012-06-12  1010        285         499.95      7.95
6082353   5809812YY75   X637251     2012-06-12  1010        30          1024.99     1.00
6082354                 T512AT0     2012-06-12  1017        172         49.95       7.95

这个交易系统的另一个限制是它不能一起发货超过4个产品。如果客户下了5个产品的订单,其中4个产品一起发货(并收取1笔运费),其余产品将单独发货,并收取另一笔运费(是的,整个业务希望重建整个遗留系统...)。

我试图确定的是每个订单发运的产品数量,以及产品总成本和运输成本。

如果你看一下MultOrderID的最后4个字符,你会发现它是连续的,YY6Y变成了YY6Z,然后滚动到YY71,YY72。逻辑是标准化的-我知道如果CustomerID、SalesDate和SalesTime是相同的,那么我可以将这些产品配对在一起。我不知道的是我如何才能做到这一点。

我认为实现这一目标的方法是分解CustomerID、SalesDate和SalesTime的订单。然后,我得到一个for-loop,或者类似的东西来循环访问各个条目。然后,我查找MultOrderID的最后4个字符,并假设1、2和3相同,并且第4个字符在前一个顺序的第4个字符之后,然后将其配对,最多4个顺序。如果orderID是该范围内的第5到第8个订单,则为发货2,依此类推。

这可以在SQL Server中完成吗?如果不在其中,我应该用什么来写这篇文章?在这种情况下,我应该使用for-loop吗?

编辑:这是我想要得到的输出。请记住,在第4个产品发货后,我需要重新开始订购(因此,6个产品被分解为2个发货4个产品和2个产品,9个产品分为3个发货4、4和1。

代码语言:javascript
运行
复制
PRODUCTSSHIPPED SALESDATE   SALESTIME   CUSTOMERID  PRODUCTCOST SHIPPINGCOST
4               6/12/12         1005    T891002     672.8       10.95
1               6/12/12         1005    T891002     99.99       7.95
2               6/12/12         1010    X637251     1524.94     8.95
1               6/12/12         1017    T512AT0     49.95       7.95
1               6/12/12         959     7661X0A     99.99       7.95
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-06-12 01:03:06

好吧,从这句话看,你似乎想要这样:

我想确定的是每个订单发货的产品数量,以及产品总成本和运输成本。

http://sqlfiddle.com/#!3/e0e71/30

所以我不确定你使用foreach循环是什么意思?

更新:

使用子查询和上限函数使其正常工作

更新了小提琴

FYI SQL是:

代码语言:javascript
运行
复制
SELECT
SalesDate,
SalesTime,
CustomerID,
SUM(ProductCost),
SUM(ShippingCost)
FROM 

(
SELECT
       SalesDate,
       SalesTime,
       CustomerID,
       ProductCost,
       ShippingCost,
       ROW_NUMBER() OVER (PARTITION BY salesdate, salestime, customerid ORDER BY CustomerID) as ProdNumber
FROM Orders
) as Summary
group by SalesDate, SalesTime, CustomerID, ceiling(ProdNumber / 4.0)

我使用ROW_NUMBER来获取每个订单的产品数量,然后将其作为一个子查询,这样我就可以进行分组。分组只使用乘积的数量除以4(作为浮点数),并使用天花板函数向上舍入到最接近的整数,从而将其分组为4

票数 2
EN

Stack Overflow用户

发布于 2012-06-12 00:55:53

这将在NumOrders字段中显示该客户/日期/时间的订单数。它使用了我最喜欢的新函数Row_Number:

代码语言:javascript
运行
复制
SELECT [CUSTOMERID], [SALESDATE], [SALESTIME], MAX(NumOrders)
FROM (
    SELECT [CUSTOMERID], 
    [SALESDATE],
    [SALESTIME],
    ROW_NUMBER() OVER(PARTITION BY [CUSTOMERID], [SALESDATE], [SALESTIME] ORDER BY [CUSTOMERID]) AS NumOrders
) t1
GROUP BY [CUSTOMERID], [SALESDATE], [SALESTIME]
票数 1
EN

Stack Overflow用户

发布于 2012-06-12 00:56:27

我认为在这里你不需要一个循环。通常,这在sql中被认为是一种糟糕的做法,除非是完全不可避免的。您是否可以假设,如果用户在相同的日期时间下了订单,那么它属于相同的逻辑顺序(顺序组)?无论如何,使用SQL server的partition and over clauses就可以解决整个问题。看这里的示例D,我认为它做了一些接近您需要的事情。

编辑

range子句仅在sql 2012中可用,但是您仍然可以使用分区和rownumber,然后通过对返回的rownumber使用简单计算(ROWNUMBER / 4)按ur结果分组

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10984241

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档