Skip to main content
Question

SQL: Using the WITH clause


Forum|alt.badge.img+10
  • Sidekick (Customer)
  • 119 replies

We were wondering if the WITH clause works in IFS. I tried one using Oracle SQL Developer and it hangs up when I run it; it doesn’t return any results. We haven’t put it in a Quick Report yet.

We’re reading InventoryPartsPerPeriod and trying to retrieve recent PO Parts until the ReceiptQty matches on OnHandQty.

Could it be because the tables in the WITH clause are too large?

WITH total_invoices ( contract, part_no, stat_period_no, quantity, i_total ) AS (
  SELECT ivpse.contract, ivpse.part_no, stat_period_no, ivpse.quantity,
         SUM( quantity ) OVER ( ORDER BY stat_year_no, stat_period_no, contract, part_no )
  FROM   REGA1APP.INVENTORY_VALUE_PART_SUM_EXT  ivpse
),

total_payments ( p_contract, p_part_no, planned_received_date, buy_qty_due, p_total ) AS (
  SELECT poi.order_no, poi.part_no, planned_receipt_date, poi.buy_qty_due,
         SUM( buy_qty_due ) OVER ( ORDER BY poi.planned_receipt_date, contract, part_no )
  FROM   REGA1APP.PURCHASE_ORDER_LINE_PART  poi
)


SELECT 
contract,
part_no,

       LEAST( p_total, i_total )
         - GREATEST( p_total - poi.buy_qty_due, i_total - ivpse.quantity ) AS used_pay_amount,
       GREATEST( i_total - p_total, 0 ) AS open_inv_amount

FROM   total_invoices  ivpse
       INNER JOIN
       total_payments   poi
	ON ( i_total - quantity < p_total
           AND i_total > p_total - buy_qty_due )


where quantity <> 0
and STAT_YEAR_NO = '2020'
and STAT_PERIOD_NO = '9'
and contract = 'W'

 

10 replies

durette
Superhero (Customer)
Forum|alt.badge.img+19
  • Superhero (Customer)
  • 525 replies
  • November 3, 2020

I frequently use the WITH clause. It works well when you know you want to force materializing a smaller result set before joining it with a larger one. If you don’t pre-filter your results, it will result in a slower execution plan.

The WITH clause doesn’t look like valid SQL in a Quick Report, so you have to wrap it with a SELECT.

SELECT * FROM (
WITH my_with AS (SELECT /*+MATERIALIZE*/ 'Hello World' AS msg FROM DUAL)
SELECT msg FROM my_with
)

(There is no such limitation when you’re creating an IAL.)


durette
Superhero (Customer)
Forum|alt.badge.img+19
  • Superhero (Customer)
  • 525 replies
  • November 3, 2020

You may want to look at the GROUP BY clause. This should be your first choice before using analytical window functions.


  • Superhero (Employee)
  • 1426 replies
  • November 4, 2020
DevBob wrote:

We were wondering if the WITH clause works in IFS. I tried one using Oracle SQL Developer and it hangs up when I run it; it doesn’t return any results. We haven’t put it in a Quick Report yet.

We’re reading InventoryPartsPerPeriod and trying to retrieve recent PO Parts until the ReceiptQty matches on OnHandQty.

Could it be because the tables in the WITH clause are too large?

WITH total_invoices ( contract, part_no, stat_period_no, quantity, i_total ) AS (
  SELECT ivpse.contract, ivpse.part_no, stat_period_no, ivpse.quantity,
         SUM( quantity ) OVER ( ORDER BY stat_year_no, stat_period_no, contract, part_no )
  FROM   REGA1APP.INVENTORY_VALUE_PART_SUM_EXT  ivpse
),

total_payments ( p_contract, p_part_no, planned_received_date, buy_qty_due, p_total ) AS (
  SELECT poi.order_no, poi.part_no, planned_receipt_date, poi.buy_qty_due,
         SUM( buy_qty_due ) OVER ( ORDER BY poi.planned_receipt_date, contract, part_no )
  FROM   REGA1APP.PURCHASE_ORDER_LINE_PART  poi
)


SELECT 
contract,
part_no,

       LEAST( p_total, i_total )
         - GREATEST( p_total - poi.buy_qty_due, i_total - ivpse.quantity ) AS used_pay_amount,
       GREATEST( i_total - p_total, 0 ) AS open_inv_amount

FROM   total_invoices  ivpse
       INNER JOIN
       total_payments   poi
	ON ( i_total - quantity < p_total
           AND i_total > p_total - buy_qty_due )


where quantity <> 0
and STAT_YEAR_NO = '2020'
and STAT_PERIOD_NO = '9'
and contract = 'W'

 

What if you add the stat_year_no and stat_period_no as columns?

 

WITH total_invoices ( contract, part_no, stat_year_no,stat_period_no, quantity, i_total ) AS (
  SELECT ivpse.contract, ivpse.part_no, ivpse.stat_year_no, ivpse.stat_period_no, ivpse.quantity,
         SUM( quantity ) OVER ( ORDER BY stat_year_no, stat_period_no, contract, part_no )
  FROM   IFSAPP.INVENTORY_VALUE_PART_SUM_EXT  ivpse
),

total_payments ( p_contract, p_part_no, planned_received_date, buy_qty_due, p_total ) AS (
  SELECT poi.order_no, poi.part_no, planned_receipt_date, poi.buy_qty_due,
         SUM( buy_qty_due ) OVER ( ORDER BY poi.planned_receipt_date, contract, part_no )
  FROM   IFSAPP.PURCHASE_ORDER_LINE_PART  poi
)


SELECT 
contract,
part_no,
stat_year_no,
stat_period_no,

       LEAST( p_total, i_total )
         - GREATEST( p_total - poi.buy_qty_due, i_total - ivpse.quantity ) AS used_pay_amount,
       GREATEST( i_total - p_total, 0 ) AS open_inv_amount

FROM   total_invoices  ivpse
       INNER JOIN
       total_payments   poi
  ON ( i_total - quantity < p_total
           AND i_total > p_total - buy_qty_due )


where quantity <> 0
and STAT_YEAR_NO = '2020'
and STAT_PERIOD_NO = '9'
and contract = 'W'

 


dsj
Superhero (Partner)
Forum|alt.badge.img+22
  • Superhero (Partner)
  • 837 replies
  • November 4, 2020

Hi @DevBob,

WITH clause is supported in IFS quick reports at least from Apps9 onwards as I recall. I checked the explain plan for the sql  and seems like it has a full table scan on purchase_order_line_tab and inventory_value_part_tab which could be the major reason for getting hangs up when running. Try to optimize the SQL to use existing indexes or otherwise you can create an IAL with schedule option and create the quick report based on the IAL.

It’s not a good idea to create a quick report with this kind of a performance hit since it could affect the IFS performance if a user tries to run it.

 

Regards,

Damith

 

 


dsj
Superhero (Partner)
Forum|alt.badge.img+22
  • Superhero (Partner)
  • 837 replies
  • November 4, 2020
durette wrote:

I frequently use the WITH clause. It works well when you know you want to force materializing a smaller result set before joining it with a larger one. If you don’t pre-filter your results, it will result in a slower execution plan.

The WITH clause doesn’t look like valid SQL in a Quick Report, so you have to wrap it with a SELECT.

SELECT * FROM (
WITH my_with AS (SELECT /*+MATERIALIZE*/ 'Hello World' AS msg FROM DUAL)
SELECT msg FROM my_with
)

(There is no such limitation when you’re creating an IAL.)

Which IFS version you have @durette, as I remember WITH clause is supported in IEE from App9 onwards


Forum|alt.badge.img+10
  • Author
  • Sidekick (Customer)
  • 119 replies
  • November 5, 2020
anmise wrote:
DevBob wrote:

We were wondering if the WITH clause works in IFS. I tried one using Oracle SQL Developer and it hangs up when I run it; it doesn’t return any results. We haven’t put it in a Quick Report yet.

We’re reading InventoryPartsPerPeriod and trying to retrieve recent PO Parts until the ReceiptQty matches on OnHandQty.

Could it be because the tables in the WITH clause are too large?

WITH total_invoices ( contract, part_no, stat_period_no, quantity, i_total ) AS (
  SELECT ivpse.contract, ivpse.part_no, stat_period_no, ivpse.quantity,
         SUM( quantity ) OVER ( ORDER BY stat_year_no, stat_period_no, contract, part_no )
  FROM   REGA1APP.INVENTORY_VALUE_PART_SUM_EXT  ivpse
),

total_payments ( p_contract, p_part_no, planned_received_date, buy_qty_due, p_total ) AS (
  SELECT poi.order_no, poi.part_no, planned_receipt_date, poi.buy_qty_due,
         SUM( buy_qty_due ) OVER ( ORDER BY poi.planned_receipt_date, contract, part_no )
  FROM   REGA1APP.PURCHASE_ORDER_LINE_PART  poi
)


SELECT 
contract,
part_no,

       LEAST( p_total, i_total )
         - GREATEST( p_total - poi.buy_qty_due, i_total - ivpse.quantity ) AS used_pay_amount,
       GREATEST( i_total - p_total, 0 ) AS open_inv_amount

FROM   total_invoices  ivpse
       INNER JOIN
       total_payments   poi
	ON ( i_total - quantity < p_total
           AND i_total > p_total - buy_qty_due )


where quantity <> 0
and STAT_YEAR_NO = '2020'
and STAT_PERIOD_NO = '9'
and contract = 'W'

 

What if you add the stat_year_no and stat_period_no as columns?

 

WITH total_invoices ( contract, part_no, stat_year_no,stat_period_no, quantity, i_total ) AS (
  SELECT ivpse.contract, ivpse.part_no, ivpse.stat_year_no, ivpse.stat_period_no, ivpse.quantity,
         SUM( quantity ) OVER ( ORDER BY stat_year_no, stat_period_no, contract, part_no )
  FROM   IFSAPP.INVENTORY_VALUE_PART_SUM_EXT  ivpse
),

total_payments ( p_contract, p_part_no, planned_received_date, buy_qty_due, p_total ) AS (
  SELECT poi.order_no, poi.part_no, planned_receipt_date, poi.buy_qty_due,
         SUM( buy_qty_due ) OVER ( ORDER BY poi.planned_receipt_date, contract, part_no )
  FROM   IFSAPP.PURCHASE_ORDER_LINE_PART  poi
)


SELECT 
contract,
part_no,
stat_year_no,
stat_period_no,

       LEAST( p_total, i_total )
         - GREATEST( p_total - poi.buy_qty_due, i_total - ivpse.quantity ) AS used_pay_amount,
       GREATEST( i_total - p_total, 0 ) AS open_inv_amount

FROM   total_invoices  ivpse
       INNER JOIN
       total_payments   poi
  ON ( i_total - quantity < p_total
           AND i_total > p_total - buy_qty_due )


where quantity <> 0
and STAT_YEAR_NO = '2020'
and STAT_PERIOD_NO = '9'
and contract = 'W'

 


thx for your suggestion. I didn’t add those because the other file, PO, doesn’t have those corresponding columns.


Forum|alt.badge.img+10
  • Author
  • Sidekick (Customer)
  • 119 replies
  • November 5, 2020
durette wrote:

You may want to look at the GROUP BY clause. This should be your first choice before using analytical window functions.


Hmm, I wasn’t aware this could be done with GROUP BY? Could you provide a simple example?


Forum|alt.badge.img+10
  • Author
  • Sidekick (Customer)
  • 119 replies
  • November 5, 2020
dsj wrote:
durette wrote:

I frequently use the WITH clause. It works well when you know you want to force materializing a smaller result set before joining it with a larger one. If you don’t pre-filter your results, it will result in a slower execution plan.

The WITH clause doesn’t look like valid SQL in a Quick Report, so you have to wrap it with a SELECT.

SELECT * FROM (
WITH my_with AS (SELECT /*+MATERIALIZE*/ 'Hello World' AS msg FROM DUAL)
SELECT msg FROM my_with
)

(There is no such limitation when you’re creating an IAL.)

Which IFS version you have @durette, as I remember WITH clause is supported in IEE from App9 onwards


We are on APPS9; I tried creating an IAL, but couldn’t translate the WITH example I found with the IALs I created.


Forum|alt.badge.img+19
  • Superhero (Employee)
  • 488 replies
  • November 6, 2020

Can you describe more detailed in words exactly what you want this query to show? Not technically but the requirement. Then it is easier to say if you are on the right way or if you need to do it differently.

The current SQL does no join on contract and part no, that is one of the things I see right now.

 

 


Forum|alt.badge.img+10
  • Author
  • Sidekick (Customer)
  • 119 replies
  • November 6, 2020
Tomas Ruderfelt wrote:

Can you describe more detailed in words exactly what you want this query to show? Not technically but the requirement. Then it is easier to say if you are on the right way or if you need to do it differently.

The current SQL does no join on contract and part no, that is one of the things I see right now.

 

 


Sure, for each part we pull in from Inventory Value Per Period we want to pull PO Items (most recent first) until the total ReceiptQty matches the OnHandQty.

So, for example, GN015CS has 412 on hand, so we want just the first PO listed- 239371 on 5/8/20202 for BuyQtyDue 1,000 because it covers the 412. If the OnHand was 3,000 we’d want the next 3 PO Items receipts as well.

 


Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings