简体   繁体   中英

Counting occurrences of an id in a database table

I'm having some trouble with an Oracle database query and the related subqueries. At it's core, the problem is count the number of times an ID from one table occurs in another table.

The Problem: I have two tables, an orders table, which stores information on ordered items from a web service. Data from that table is run through a process (which I have no control over) and the result is placed into a fulfilled table.

Order numbers are not unique to one item. Each order can have a large number of items, and each item is stored on a line . Items, however, can actually be a combo/package and that is what the process handles. An item, GAME_PACK for example, can come into the orders table and out on the other end comes out GAME1, GAME2, GAME3 and are associated by the order number.

表示订购过程的简单图

The problem is, occasionally these items don't come out of the process correctly and then a line_item may not be associated with a fulfilled item. The only way I can, with the resources available, determine if there is an issue is by getting the maximum line_number and comparing that to the number of fulfilled_item groups.

What I've tried: At first I thought it would be fairly simple to do, simply using a rownumber() or denserank() analytical function over a partition by the order number, but it has become much more confusing than that. This is currently the query I am working with:

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%'

note that right now I am pulling when the counts match, this logic will be reversed when I am certain the query works

Constraints

  • I do not have access to the process that splits the items
  • The query should run quickly, we are working with upwards of 50,000 possible records
  • The query was tested at 22 seconds to over 2 minutes execution time
  • Pagination is going to be used, if you answer, don't worry about including it, but it is something to consider because it can greatly help or hurt the speed of the query
  • I cannot touch table structure

Table Structure and Graphic Representation 流程运行后,订单表和已完成项目表之间的关系 (Maximum line number represents the number of fulfilled_item groups)

Thank you for taking the time to read this.

EDIT Results should look something like this: 查询的样本输出

where item comes from the orders table, and result is OK, BAD based on whether or not the fulfilled groups matches the max line number.

If I'm understanding correctly, each order should have the same number of fulfillment groups as there are line numbers in the order. Each fulfillment group will be of unknown size and be represented by a unique fulfillment number. Based on that, I think the query should be as simple as this:

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

The subquery counts the number of lines (just in case a line number gets skipped, but you could change this back to a max on the line number if you really want to) and the number of distinct fulfillment groups. The overall query returns those orders where the two counts are not equal.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM