当前位置: 首页 > 面试题库 >

TSQL将结果集平均划分为组并进行更新

应和光
2023-03-14
问题内容

订单表具有如下数据:

OrderID    OperatorID    GroupID        OrderDesc    Status    Cash    ...
--------------------------------------------------------------------------
      1             1          1      small order         1     100 
      2             1          1    another order         2       0 
      3             1          2      xxxxxxxxxxx         2    1000 
      5             2          2      yyyyyyyyyyy         2     150 
      9             5          1      xxxxxxxxxxx         1       0 
     10          NULL          2      xxxxxxxxxxx         1      10 
     11          NULL          3      xxxxxxxxxxx         1     120

运算符表:

OperatorID    Name    GroupID    Active
---------------------------------------
      1       John          1         1
      2       Kate          1         1
      4       Jack          2         1
      5       Will          1         0
      6        Sam          3         1

组表:

GroupID    Name
---------------
      1      G1
      2      G2
      3      X1

如您所见,约翰有3个订单,凯特(Kate),威尔(Will),杰克(Jack)和山姆(Sam)没有。

现在,我想根据某些条件将操作员分配给订单:

  • 订单现金必须大于0
  • 订单必须具有状态= 1
  • 订单必须在组1或2中
  • 操作员必须处于活动状态(active = 1)
  • 操作员必须在组1或2中

这是我想要得到的结果:

OrderID    OperatorID    GroupID        OrderDesc    Status    Cash    ...
--------------------------------------------------------------------------
      1             1          1      small order         1     100       < change
      2             1          1    another order         2       0 
      3             2          2      xxxxxxxxxxx         2    1000       < change
      5             4          2      yyyyyyyyyyy         2     150       < change
      9             5          1      xxxxxxxxxxx         1       0 
     10             4          2      xxxxxxxxxxx         1      10       < change
     11          NULL          3      xxxxxxxxxxx         1     120

我想重新整理订单并更新operatorID,以便每次调用此脚本时都会得到随机的分配者operatorID,但是每个运算符将具有相等的数字或订单(接近相等,因为如果我有7个订单,那么一个人将拥有3个并且其余2)。

我可以用来NTILE将订单分配到组中,但是我需要为该组分配operatorID。

我认为我需要做这样的事情:

SELECT NTILE(2) OVER( order by orderID desc) as newID,* 
FROM
    orders(NOLOCK)

这将使我的订单表分成相等的部分。我需要知道的是运算符表的长度(将其作为参数添加到NTILE中),之后我可以将结果与运算符合并(使用row_number()

有更好的解决方案吗?

再次我的问题是: 如何将结果集平均划分为组,并使用另一个表数据更新该记录集?

编辑: 这是到目前为止我的代码:http :
//sqlfiddle.com/#!3/39849/25

编辑2 我已经更新了我的问题,并添加了更多条件。

我想根据某些条件将操作员分配给订单:

  • 订单现金必须大于0
  • 订单必须具有状态= 1
  • 订单必须在组1或2中
  • 操作员必须处于活动状态(active = 1)
  • 操作员必须在组1或2中

我将这个查询构建为存储过程。
因此,第一步将是将具有新赋值的数据生成到临时表中,并在最终批准之后在第二步中基于该临时表更新主表。

我还有2个问题:

  1. 首先选择所有满足条件的所有订单和所有运算符到临时表,然后进行改组还是在一个大查询中全部完成,会更好吗?

  2. 我想将数组或组作为参数传递给我的程序。哪种选择是将数组传递到存储过程的最佳选择(SQL Server 2005)。

我知道这个问题被问过很多次,但我想知道是否最好创建一个单独的函数来将逗号分隔的字符串切成表格(http://www.sommarskog.se/arrays-
in-sql-2005.html)还是将所有内容都放入一个大胖子程序中?:)

最终答案:可
通过http://sqlfiddle.com/#!3/afb48/2获得

SELECT o.*, op.operatorName AS NewOperator, op.operatorID AS NewOperatorId
FROM (SELECT o.*, (ROW_NUMBER() over (ORDER BY newid()) % numoperators) + 1 AS randseqnum
      FROM Orders o CROSS JOIN
     (SELECT COUNT(*) AS numoperators FROM operators WHERE operators.active=1) op
      WHERE o.cash>0 and o.status in (1,3)
     ) o JOIN
     (SELECT op.*, ROW_NUMBER() over (ORDER BY newid()) AS seqnum
      FROM Operators op WHERE op.active=1
     ) op
     ON o.randseqnum = op.seqnum ORDER BY o.orderID

答案基于戈登的Linoff答案。谢谢!


问题答案:

我不确定您是否真的想要更新查询或选择查询。以下查询根据您的条件为每个订单返回一个新的运算符:

/*
with orders as (select 1 as orderId, 'order1' as orderDesc, 1 as OperatorId),
     operators as (select 1 as operatorID, 'John' as name)
 */
select o.*, op.name as NewOperator, op.operatorID as NewOperatorId
from (select o.*, (ROW_NUMBER() over (order by newid()) % numoperators) + 1 as randseqnum
      from Orders o cross join
     (select COUNT(*) as numoperators from operators) op
     ) o join
     (select op.*, ROW_NUMBER() over (order by newid()) as seqnum
      from Operators op
     ) op
     on o.randseqnum = op.seqnum order by orderid

它基本上为联接的行分配了一个新的id。订单表的值介于1到随机分配的运算符数量之间。然后将其与运算符上的序列号连接在一起。

如果需要更新,则可以执行以下操作:

with toupdate as (<above query>)
update orders
    set operatorid = newoperatorid
    from toupdate
    where toupdate.orderid = orders.orderid

您的两个问题:

首先选择所有满足条件的所有订单和所有运算符到临时表,然后进行改组还是在一个大查询中全部完成,会更好吗?

临时表的用户取决于应用程序的性能和要求。如果数据正在快速更新,那么可以,使用临时表是一个很大的胜利。如果对同一数据多次执行随机化操作,那将是一个成功,特别是如果表太大而无法容纳在内存中时。否则,假设您将条件放在最里面的子查询中,那么一次运行就不会有很大的性能提升。但是,如果性能是一个问题,则可以测试这两种方法。

我想将数组或组作为参数传递给我的程序。 哪种选择是将数组传递到存储过程的最佳选择(SQL Server 2005)。

嗯,切换到具有表值参数的2008。这是Erland
Sommarskog撰写的有关该主题的高参考文章:http : //www.sommarskog.se/arrays-in-
sql-2005.html。



 类似资料:
  • 问题内容: 我有一个这样的数据框: 我想计算每个集群每个组织的平均时间。 预期结果: 我不知道如何在熊猫中做到这一点,有人可以帮忙吗? 问题答案: 如果你想先对组合取平均值,然后再对cluster组取平均值 如果你不仅仅希望价值观,那么你可以 你可以groupby上再取

  • 问题内容: 我试图通过取元素的平均值将numpy数组分组为较小的大小。例如,将100x100阵列中的平均5x5子阵列的foreach平均值创建20x20大小的阵列。由于需要处理大量数据,这是一种有效的方法吗? 问题答案: 我已经尝试过使用较小的阵列,因此请与您的阵列进行测试: 6x6-> 3x3的示例:

  • 我希望PostgreSQL将查询结果作为一个JSON数组返回。给定 我想要类似于

  • 问题是关于阿克卡演员图书馆。A想把一个大任务分成几个小任务,然后把它们的结果合并成一个“大”结果。这将给我更快的计算利润。如果较小的任务是独立的,则可以并行计算它们。 假设我们需要这样计算。函数非常耗时,因此在一个线程中多次使用它并不理想。 问题来了。 如何分派任务、收集结果,然后折叠它们,所有这些都使用akka actors?Akka已经提供了这样的功能,还是我需要自己实现?这种方法的最佳实践是

  • 问题内容: 我有这样一个浮点数组: 现在,我想像这样对数组进行分区: // [200]由于集群支持较少,将被视为异常值 我必须为多个数组找到这种段,但我不知道分区大小应该是多少。我试图通过使用层次聚类(聚集)来做到这一点 ,它为我提供了令人满意的结果。但是,问题是,建议我不要对一维问题使用聚类算法,因为这样做没有任何理论上的依据(因为它们是针对多维数据的)。 我发现了另一个建议,而不是聚类,即自然

  • 问题内容: 我需要将结果集转换为字符串数组。我正在从数据库中读取电子邮件地址,我需要能够像这样发送它们: 这是我的阅读电子邮件地址的代码: MyOutput是: 我需要这样: 我正在使用Oracle 11g。 问题答案: 获得所需的输出: 替换这些行 通过