【问题标题】:Select row above and row(s) between next matching row or last row选择上面的行和下一个匹配行或最后一行之间的行
【发布时间】:2010-12-30 19:45:36
【问题描述】:

这可能是一个愚蠢的问题,或者我可能一次问太多了:

简而言之
如何在两次出现“B/O INFO %”之类的描述或“B/O INFO %”与给定订单号的最后一行之间的表中选择行(WHERE OrderNo = 12345678)

背景
我正在尝试为我们的业务客户整理一份未结订单行项目报告。为了回答这个问题,我正在使用的旧的但“经过验证的”数据库及其设计和写入它的进程应该被认为是不可变的(主要是因为向该表写入数据的进程很难处理 {Unisys 大型机上的 COBOL、大型机到 MSSQL 的复制、没有完全合格的 Unisys 大型机 COBOL 程序员可用、迁移 大型机等})。

我 2 周以来一直在尝试完成的是创建一个 SELECT 语句,该语句返回订单和订单行项目的层次结构。此层次结构表示我们的客户下的订单以及所有生成的“子”订单,它们试图从“根”订单中填充(全部或部分)订单项。

下订单时,会应用许多自动化和手动流程。如果系统发现订单行项目可以完全通过从不同仓库发货来完成,它将为这些行项目创建一个新的子订单。如果订单项数量不可用,它将部分发货并为剩余部分创建延期交货。如果客户真的需要该订单项,人工将手动创建一个新订单,从不同位置采购零件。

问题
令人沮丧的情况是一个非索引 char(21) 列用于声明子订单中的哪些行项目适用于给定的父订单,并且该链接信息与实际订购的产品不在同一行 - 它是一个完全独立的“评论”行。我遇到真正的麻烦是试图从这些子订单中选择特定的订单行项目。最麻烦的是选择订单行项目匹配描述模式的两个实例或订单行的末尾。

我已经尝试过各种 JOIN 和 WHERE 等。我不是 DBA,但我远远高于“知道足够危险”的水平,而且我已经走到尽头,试图得到这个在一起。

我需要/想要做什么
创建一个存储过程,该过程返回订单层次结构中所有订单号及其各自项目号的结果集,然后我可以使用它来确定根订单行项目的数量履行情况。

详情
子订单中的这些注释行与其父订单的关联方式如下:

  1. 以“@???/”开头的描述表示已创建子订单(参见下面的 #2),订单号与斜线之间的数字匹配。
  2. 以“MEO INFO”开头的描述表示订单中的所有项目(参见上面的#1)都与描述的数字部分匹配的订单相关。
  3. 以“*S/”开头的描述表示已创建子订单(请参见下面的#4),订单号与斜线之间的数字匹配。
  4. 以“B/O #”开头的描述意味着上面的行与描述的数字部分匹配的订单相关。 (参见上面的#3)
  5. 以“B/O INFO”开头的描述意味着在下一次出现“B/O INFO”或订单行项目的结尾之前至少有一行与描述的数字部分匹配的订单相关.父级将不会引用此子级订单。
  • 包含“B/O #”或“B/O INFO”等行 cmet 的订单可以是“复合”子订单,用于履行来自一个或多个父订单的订单行项目。上述列表中详述的相关订单项。
  • 在订单中查找“@???/”和“*S/”行很容易引用子订单。

使用此示例数据,根订单号为 12345678,我需要构建所有相关子订单项的层次结构。
示例数据

OrderNo |ItemNo |描述 |LineCD
-------------------------------------------------
指向子订单的行
12345678 1 @LVL/11223344/001
12345678 2 *S/11335577/12345ELEM

与父订单相关的所有行
11223344 1 MEO 信息 12345678
11223344 2 轨
11223344 3 身体烤箱焊接ASM

注释行表示上面的行是针对父订单的
55667788 1 泵&电机
55667788 2 电动车#12345678
55667788 3 *S/22446688/12345GLAS
55667788 4 B/O # 77553311 //以上行与12345678无关

注释行指示下面的行直到行尾或
下一条评论是针对父订单的
98765432 31 电动车信息 12345678 C
98765432 32 CNTRL-ELEC
98765432 33 罢工
98765432 34 控制电气
98765432 35 电动车信息 88664422 C

我希望这个问题是可以回答的。如果没有,它至少会让你的大脑得到很好的锻炼。

【问题讨论】:

  • 看来您基本上是在要求我们为您解决问题?
  • 好吧,我将省略到目前为止我编写的整个过程 - 问题变得相当长。我最大的问题是试图在一次出现的“B/O INFO”和下一个“B/O INFO”或最后一个订单行项目之间进行选择。如果有人可以提出一种方法来做到这一点,那可能会很快解决这个问题。
  • 不是 StackOverflow 问题中最时髦的。也许对这个问题感兴趣的“另一个程序员”就坐在你旁边?你至少可以像...一样切入主旨吗??
  • 抱歉,对于“向社区提问”这个场景还很陌生,我喜欢提供信息而不是盲目提问。也许这就是问题所在——我没有。我在顶部添加了一个汇总请求。

标签: tsql stored-procedures select join


【解决方案1】:

哇,真是一团糟。

虽然我讨厌推荐使用游标,但我没有看到任何其他方法来获取您想要的数据。我不认为基于标准集的操作(带有连接的选择等)会以任何合理的方式提取数据。

这给我们留下了 3 个潜在的解决方案。

一,在您的代码中进行处理。根据数据集的大小,这有许多明显的缺点。

二,使用游标进行处理。游标的性能不是很好,但是以这种方式构建的数据甚至不会引起人们的注意。

三,使用某种类型的基于 CLR 的解决方案。这里的缺点是你的安装能力以及你的 sql server 是否支持。

祝你好运。

【讨论】:

  • 在尝试完成这两个多星期后,我得出的结论是,确实,解决方案是以某种程序方式逐步检查每个订单行项目(在代码中,使用光标等)。但我还发现,我们的数据库设计和下订单的不同方式的数量使得问题的完全解决方案基本上是不可能的(如果不是用大写的“F”非常难看的话)。
【解决方案2】:

这真的很复杂,我不确定我是否完全理解它,但我认为好的输出应该是这样的:

ParentID ChildID ItemNo 描述(作为结果集)

将所有 B/O、B/O INFO 和 S/ 转换为父/子关系,并且根订单的父 ID 为空白。这需要在一次通过源表期间在内存中构建订单行(和关系)表。

如果在内存中构建它是不可接受的,并且您有性能问题,我建议您考虑输出这个单一的结果集,而不是通过两次传递:

ChildID ItemNo 描述(过滤掉 S/B/O B/O INFO)

联合

ChildID ItemNo Description(ItemNo 始终为零,Description 设置为 ParentID)

如果您必须将结果临时放在某个地方,它应该放在另一个表空间中。

并验证结果集输出的使用者(例如 Excel 或您的 DSS 包)中的父子关系。

这样至少会发生一些翻译/压缩/合理化,网络使用减少,关键字段不太好,混淆。这可能是一个更好的解决方案,但从问题中不清楚优先级和问题是什么。

这听起来很像现实生活。一个优雅的(甚至可能是值得推荐的)无解决方案区。

编辑

降低网络使用率可能比我建议的要难。

在两遍解决方案中,我建议为 B/O 小节提供类似的键

97387326(在 B/O 或 B/O INFO 部分之前)

97387326-1(第一个 B/O 或 B/O INFO 部分的一部分)

97387326-2(第二个 B/O 或 B/O INFO 部分的一部分)

(等)

【讨论】:

    猜你喜欢
    • 2020-12-28
    • 2015-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-19
    • 2015-03-13
    • 1970-01-01
    相关资源
    最近更新 更多