TSQL 将结果集均分并更新

2024-04-14

我的数据库有 3 个表,如下所示:

Orders 表的数据如下:

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

正如您所看到的,John 有 3 个订单,Kate 1 个,Will 1 个,Jack 和 Sam 没有。

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

  • 订单必须有现金>0
  • 订单状态必须为 1
  • 订单必须属于组 1 或组 2
  • 操作员必须处于活动状态(活动=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 

我想洗牌订单并更新操作员ID,以便每次调用此脚本时我都会获得随机分配者操作员ID,但每个操作员都会有相同的数量或订单(接近相等,因为如果我有7个订单,一个人将有3个订单,其余的2)。

我可以用NTILE将订单分配到组中,但我需要将操作员 ID 分配给该组。

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

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

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

有更好的解决方案吗?

我的问题又来了:如何将结果集均等分组并使用另一个表数据更新该记录集?

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

EDIT 2我更新了我的问题并添加了更多条件。

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

  • 订单必须有现金>0
  • 订单状态必须为 1
  • 订单必须属于组 1 或组 2
  • 操作员必须处于活动状态(活动=1)
  • 操作员必须属于组 1 或组 2

我正在将此查询构建为存储过程。
因此,第一步是生成具有新分配的数据到临时表中,并在第二步最终批准后根据该临时表更新主表。

我还有 2 个问题:

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

  2. 我想将数组或组作为参数传递给我的过程。哪个选项最适合将数组传递给存储过程 (SQL Server 2005)。

    我知道这个问题被问过很多次,但我想知道是否最好创建一个单独的函数来将逗号分隔的字符串剪切到表中(http://www.sommarskog.se/arrays-in-sql-2005.html http://www.sommarskog.se/arrays-in-sql-2005.html)或者把所有东西都放在一个大的程序中? :)


最终答案:可以在http://sqlfiddle.com/#!3/afb48/2 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

答案基于戈登的利诺夫答案。谢谢!


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

/*
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 http://www.sommarskog.se/arrays-in-sql-2005.html.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

TSQL 将结果集均分并更新 的相关文章

  • 在 MySQL 中存储 IPv6 地址

    正如 需要支持 ipv6 的 inet aton 和 inet ntoa 函数 http bugs mysql com bug php id 34037 目前没有用于存储 IPv6 地址的 MySQL 函数 用于存储 插入的推荐数据类型 函
  • SQL 中的模糊分组

    我需要修改 SQL 表以对稍微不匹配的名称进行分组 并为组中的所有元素分配标准化名称 例如 如果初始表如下所示 Name Jon Q John Q Jonn Q Mary W Marie W Matt H 我想创建一个新表或向现有表添加一个
  • 当我传递 NULL 值时,COALESCE 函数不起作用,但当将变量声明为 NULL 时它起作用

    当我执行以下查询时 我得到输出 但是当我通过NULL参数 它不起作用 示例1 DECLARE a int NULL b int NULL c int NULL SELECT COALESCE a b c GO 输出 空 示例2 SELECT
  • 带有mysql的实体框架,linux和windows之间的表大小写问题

    我们目前正在开发一个使用 Code First Entity Framework 和 Mysql 的产品 开发数据库托管在 Windows 环境中 而生产 mysql 则托管在 Linux 环境中 我遇到的问题是 mysql 中的表命名如下
  • 无法使用 LISTAGG

    SELECT deptno LISTAGG ename WITHIN GROUP ORDER BY ename AS employees FROM emp GROUP BY deptno Error ORA 00923 FROM keywo
  • 在SSIS中导入已合并单元格的Excel

    我的问题是在读取合并 组合列单元格的 Excel 文件时 例如 将下面的excel数据读取到数据库中 Excel 输入 ID NAME DEPT FNAME LNAME 1 Akil Tiwari IT 2 Vinod Rathore IT
  • 为什么sql表名中通常使用下划线而不是驼峰式大小写[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 是否需要显式事务回滚?

    许多例子都主张显式回滚数据库事务 大致如下 using var transaction try do some reading and or writing here transaction Commit catch SqlExceptio
  • 递归 CTE 中的 TSQL GROUP BY

    是否有解决方法可以在循环 CTE 内使用 GROUP BY 或者有解决方法 我需要对 CTE 表的结果集进行分组 并在具有相同 CTE 的另一个循环中使用它 但出现以下错误 不允许使用 GROUP BY HAVING 或聚合函数 递归公用表
  • Athena date_parse 用于具有可选毫秒字段的日期

    我在 S3 中有日期 使用它创建了 Athena 表 我在 S3 中有一些 json 格式的日期条目 在运行查询时 Athena 不接受这些条目作为日期或时间戳 使用 AWS Athena 它使用 Prestodb 作为查询引擎 示例 js
  • 将 SQL 依赖关系与 Azure 结合使用

    在我的本地数据库中 Sql 依赖关系工作正常 但是当我迁移到 Azure 数据库时 它就不起作用了 我检查服务代理是否已启用 并且它已激活 这是错误 此版本的 SQL Server 不支持语句 RECEIVE MSG 这是我的代码 publ
  • Android SQLite 列.....不是唯一的

    我在 Android 上使用 SQLite 并收到此错误 02 11 18 05 37 224 E SQLiteDatabase 26583 android database sqlite SQLiteConstraintException
  • 在 pymssql 中重复死锁查询后更新失败

    我将 SQL Server 与 pymssql 一起使用 发现一个特别复杂的 SELECT 查询偶尔会被选为死锁受害者 因此 我将其包装在 while 循环中 以便在发生这种情况时重试事务 大致如下 while True try curso
  • MySQL“插入...重复键”具有多个唯一键

    我一直在阅读如何使用MySQL在重复键上插入 看看它是否允许我避免选择一行 检查它是否存在 然后插入或更新 然而 当我阅读文档时 有一个地方让我感到困惑 文档是这样说的 如果指定 ON DUPLICATE KEY UPDATE 并且插入的行
  • 如何将 SELECT...INTO 与 JOIN 一起使用?

    我有以下示例代码 DECLARE myRow table rowtype myVar table2 column type BEGIN SELECT table col1 table col3 table col4 table2 colum
  • 从文件执行db语句

    我在我的应用程序中使用嵌入式 Apache derby 我有一个名为的 SQL 脚本创建的数据库 sql创建数据库中的所有表并用初始数据填充它 例如 SET SCHEMA APP CREATE TABLE study study id bi
  • 如何计算 MySQL 中日期的平均值?

    如何在 MySQL 中计算日期之间的平均值 我对时间值 小时和分钟更感兴趣 在桌子上有 date one datetime date two datetime 执行如下查询 SELECT AVG date one date two FROM
  • 显示 Presto 中所有模式的表

    急速 SHOW SCHEMAS 返回所有模式 SHOW TABLES FROM foo 返回 foo 模式的所有表 有没有一种简单的方法可以从 Presto 中的所有模式返回表 您可以使用select table schema table
  • 如何找到与日期范围最重叠的时间段

    假设您有一个包含标识符 开始时间和结束时间的表 这些开始和结束时间可以是任意时间长度 开始时间始终早于结束时间 假设没有空值 什么样的查询会告诉我最 流行 的时间 即每行中的两个范围与大多数其他行重叠的位置 它的实际应用是它是一个记录用户登
  • MYSQL枚举:@rownum,奇偶记录

    我问了一个关于为查询结果创建临时 虚拟 ID 的问题 mysql 和 php 查询结果的临时 虚拟 ID https stackoverflow com questions 4063998 mysql php temporary virtu

随机推荐

  • 使用 OpenCV 对非正面图像进行人脸检测

    我正在尝试使用 opencv 来检测人脸 脸部不是正面 相机从侧面拍摄脸部 因此只能看到一只眼睛和部分嘴巴 我尝试了具有多种配置的 HaarDetectObjects 但没有获得任何好处 我改变了级联并进行了测试 haarcascade f
  • 在折线图中的特定点添加标记

    我正在绘制一个绘图线图 并希望使用标记突出显示线图上的特定点 其中数据框中的另一列不是 NA 此外 当我将鼠标悬停在绘图上时 我只想查看位于标记点上的 y 值 而不是绘图的其余部分 这是一个可重现的示例 到目前为止我已经尝试做到这一点 li
  • 使用 Python 检测 OpenCV 中的线条和形状

    我一直在使用 OpenCV cv2 并检测线条和形状 假设我女儿画了一幅图画 如下所示 我正在尝试编写一个Python脚本来分析绘图并将其转换为硬线条 形状 例如 话虽这么说 我已经安装了 opencv 并尝试使用它 但除了能够在图像中绘制
  • 如何设置扭曲的日志记录级别?

    我正在使用带有twisted的autobahn包 它会在每次连接到websocket时显示调试消息 我尝试将日志记录级别切换为信息但没有成功 import logging logging basicConfig level logging
  • 如何通过 Java 运行我的 haskell 函数

    假设我有一个 haskell 函数add in math hs 我怎样才能运行add通过Java程序运行函数并将输出存储为变量 也许像下面这样 public int runHaskell String haskellFile int out
  • 如何在 MATLAB 中编写向量化函数

    我刚刚学习MATLAB 我发现很难理解循环与矢量化函数的性能因素 在我之前的问题中 MATLAB 中的嵌套 for 循环非常慢 预分配 https stackoverflow com q 7811239 518169我意识到使用向量化函数与
  • 从传递给 C# 的 F# 列表中检索项目

    我在 C 中有一个在 F 中调用的函数 将其参数传递到Microsoft FSharp Collections List 如何从 C 函数中的 F 列表中获取项目 EDIT 我找到了一种 函数式 风格的方式来循环它们 并且可以将它们传递给如
  • docker-compose 构建镜像或构建上下文[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我想构建自定义 Dockerfile 但我收到以下消息 gt Starting build app ERROR The Compose f
  • iText 列表项或 JTextArea 中的行间距

    我需要在 GUI 中同步 PDF 列表项和 JTextArea 的行距 我可以通过调整其中之一来做到这一点 在列表项 或 JTextArea 超过一行 在 JTextArea 中将换行设置为 true 之前 这一切都运行良好 我可以调整两个
  • 根据属性检查 firebase 是否存在现有对象,防止重复

    我想检查我的 firebase 看看我是否已经存储了一个与两个属性匹配的对象 为了将这个问题放在上下文中 想象一个仅存储歌曲的应用程序 具有 艺术家 和 歌曲名 等属性 如下所示 var wishlist new Firebase http
  • 在 Windows 10 家庭版 docker-compose.yml 文件中设置卷

    尝试设置 docker 以便当我在 Windows 计算机上更改项目文件时 它们会在我的 docker 容器中更新 从这个问题 https stackoverflow com questions 41925212 changing my p
  • 如何按日期在 R 中对大型数据框 (ffdf) 进行子集化?

    我正在尝试按日期对 FFDF 进行子集化 下面 我使用普通数据框成功创建了这样的子集 但我需要一些帮助才能将其应用到 FFDF 我的尝试以及错误消息都列在代码注释中 提前谢谢了 Create a normal data frame in p
  • 如何保持片段视图状态?

    我对碎片系统有疑问 我有两个片段 例如A and B 如果我搬家A to B Navigation findNavController v navigate R id B Now A片段 onDestroyView 被称为我知道这是正常的
  • 使用 Imagick 将图像从 RGB 转换为 CMYK

    我正在尝试将 RGB 图像转换为 CMYK 因为它们需要打印 我正在使用这段代码
  • JavaScript 中 /// 是什么意思?

    双正斜杠 是 JavaScript 中的注释 但是三重正斜杠是什么意思 意思是 我问的原因是当我删除具有以下内容的行时代码会中断 这让我相信 不是评论 可能是一个参考指令 https stackoverflow com questions
  • 使用 Bluebird 进行 Mongoose 承诺的正确方法是什么?

    我一直在阅读文档和文章 每个人似乎都描述了一起使用 Mongoose 和 Bluebird 的不同方式 甚至 Mongoose 官方文档说了些什么 http mongoosejs com docs promises html蓝鸟文档说另一件
  • BOOST_LIKELY 和 __builtin_expect 仍然相关吗?

    我明白所解释的内容here https stackoverflow com questions 7346929 why do we use builtin expect when a straightforward way is to us
  • ListBox MVVM 中的清除选择

    在 MVVM Silverlight 应用程序中 用户可以在 TextBox 中输入文本 并且 ListBox 内容会相应更改 例如 如果用户输入 TV 列表框将填充所有可用的电视品牌 并且用户可以从列表框和列表框条目中选择产品 接下来 如
  • 在运行 ActionEvent 之前 GUI 不会在视觉上更新

    为了详细说明一下 我有一个如下所示的 GUI 然后我在 确定 按钮上有一个动作侦听器 其开头如下 OK Button Action Listener private void okButtonActionPerformed ActionEv
  • TSQL 将结果集均分并更新

    我的数据库有 3 个表 如下所示 Orders 表的数据如下 OrderID OperatorID GroupID OrderDesc Status Cash 1 1 1 small order 1 100 2 1 1 another or