简体   繁体   中英

Oracle Query - Filter and Limit in two tables using JOIN

I am facing an issue in Oracle Query to achieve the following use case,

Consider I have two tables:

Table 1 : product
     productId - Integer - primaryKey
     productName - Varchar 

Table 2 : product_sequence
     productId - Integer - primaryKey
     sequenceId - Integer - primaryKey 
     orderId - Integer
     orderName - Varchar

product table has 1000 entries and product_sequence table has 10K entries

Requirement :

  1. (paginate) fetch the entries from 0 to 100 / 100 to 200 / etc., in the product table
  2. Distinct count of productId for showing the pagination in UI (check the sample query below)
  3. Filter by 'productName' in 'product' table and 'orderName' in 'product_sequence' table

Query (tried) :

SELECT
  p.productId, p.productName, ps.orderId, ps.orderName, 
  COUNT(distinct p.productId) OVER () AS TOTAL 
FROM (
  select * 
  from product 
  OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY
 ) p 
JOIN product_sequence ps on p.productId=ps.productId 
WHERE ps.orderId IN ('12','13','14');

NOTE: the above query will work in Oracle, But the issue is

Expected : Return 100 entries from 'product' table with mapped entries in the 'product_sequence' table

Actual : It first LIMITS 100 entries in product and then filter the orderId so the number of entries returned is reduced from 100 to lesser number I agree my query is not correct : It first LIMIT by 100 in 'product' table in subquery and then goes for filter in second table which reduces the count

Could some one help me with the query for this please? Anyhelp is appreciated.
If my question is not clear, Let me know, I can explain with more info.

Try to move the OFFSET and FETCH clauses to the outer query, something like this:

SELECT q.productId, q.productName, q.orderId, q.orderName,
       COUNT(distinct p.productId) OVER () AS TOTAL
FROM ( SELECT * FROM product p JOIN product_sequence ps ON p.productId = ps.productId
       WHERE ps.orderId IN ('12','13','14') ) q
OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY

To get 100 rows per page "after filtering" you'll need to find all the productid values first, then process the main query.

For example:

select
  p.productid, p.productname, ps.orderid, ps.orderName,
  count(distinct p.productid) over() as total
from product p
join product_sequence ps on p.productid = ps.productid
where ps.orderid in ('12','13','14')
and p.productid in (
  select *
  from (
    select distinct p.productid
    from product p
    join product_sequence ps on p.productid = ps.productid
    where p.productname like '%theremin%' -- filter #1
      and ps.orderid in ('12','13','14')  -- filter #2
  ) x
  order by productid
  offset 300 rows -- get the 4th page
  fetch first 100 rows only -- page size set to 100 rows
)

See example at db<>fiddle .

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