计算数据库表中id的出现次数

时间:2015-07-23 17:22:07

标签: sql database oracle oracle11g oracle10g

我在使用Oracle数据库查询和相关子查询时遇到了一些问题。在它的核心,问题是计算一个表中的ID出现在另一个表中的次数。

问题: 我有两个表,一个订单表,它存储来自Web服务的订购商品的信息。该表中的数据通过一个进程运行(我无法控制),并将结果放入一个已完成的表中。

订单号对于一个商品而言是唯一的。每个订单都可以包含大量商品,每个商品都存储在中。但是,项目实际上可以是组合/包,这是流程处理的内容。一个项目,例如GAME_PACK,可以进入订单表,另一端出来的是GAME1,GAME2,GAME3,并且与订单号相关联。

Simple diagram representing the order process

问题是,有时这些项目不会正确地退出流程,然后line_item可能与已完成的项目无关。在可用资源的情况下,我可以通过获取最大line_number并将其与fulfilled_item组的数量进行比较来确定是否存在问题的唯一方法。

我尝试了什么: 起初我认为这样做很简单,只需在订单号上使用rownumber()denserank()分析函数,但它已经变得更加混乱了。 这是我正在处理的查询:

select * 
from(
    select max (item_index) over (partition by tbl.item_number) item_count, tbl.*
        from (
            select i.item_fulfill_number, i.order_number, row_number()over(partition by i.item_number, i.order_number order by i.order_number) item_index 
            from fulfilled_items i ) tbl
            ) results 
            inner join (
                select * 
                from (
                    select orderinfo.order_number as order_order_number, orderinfo.line_number, orderinfo.ordered_item, row_number() over(partition by orderinfo.order_number order by orderinfo.line_number desc) order_row 
                    from orderinfo
                    ) 
                where order_row <= 1
                )
            on results.order_number = order_order_number
where results.item_count = results.item_index and ordered_item like 'GAME%'

请注意,现在我在计数匹配时拉动,当我确定查询有效时,此逻辑将被反转

约束

  • 有权访问拆分项目的过程
  • 查询应该快速运行,我们的工作量超过50,000 可能的记录
  • 查询在22秒到超过2分钟的执行时间进行了测试
  • 将使用分页,如果你回答,不要担心 包括它,但它是值得考虑的因为它可以很大 帮助或损害查询的速度
  • 我无法触摸表格结构

表格结构和图形表示 The relation between the orders table and the fulfilled items table after the process has run(最大行数表示fulfilled_item组的数量)

感谢您抽出宝贵时间阅读本文。

修改 结果应如下所示: a sample output for the query

其中item来自orders表,结果是OK,BAD基于已完成的组是否与最大行号匹配。

1 个答案:

答案 0 :(得分:0)

如果我理解正确,每个订单的履行组数应与订单中的行号相同。每个履行组的规模都是未知的,并由唯一的履行号码表示。基于此,我认为查询应该像这样简单:

SELECT 
  main.*, 
  'BAD' AS result
FROM (
    SELECT DISTINCT
      o.order_number,
      COUNT(o.line_number) OVER (PARTITION BY o.order_number) AS order_lines,
      (SELECT COUNT(DISTINCT item_fulfill_number) FROM fulfilled_items f WHERE f.order_number = o.order_number) AS fulfilled_groups
    FROM orders o
) main
WHERE order_lines != fulfilled_groups

子查询计算行数(以防万一跳过行号,但如果你真的想要,可以将其更改回行号的最大值)和不同的履行组的数量。整个查询返回两个计数不相等的那些订单。