I want to optimize 2 queries from 2 tables(orders, actions
) with relation one to many
Now I make one select from orders:
SELECT "id"
FROM "orders"
WHERE "orders"."status" = 'new'
Then for each order I select:
SELECT *
FROM "actions" AS "actions"
WHERE "actions"."status" IN ( 'new', 'processing' )
AND "actions"."order_id" = ${orderId}
ORDER BY CASE
WHEN ( "status" = 'processing' ) THEN 0
WHEN( "status" = 'new' ) THEN 1
ELSE 2
END ASC,
CASE
WHEN ( "direction" = 'out' ) THEN 0
WHEN( "direction" = 'in' ) THEN 1
ELSE 2
END ASC,
"actions"."id" ASC
LIMIT 1;
Action table contain due_date
, with results from actions, in code, I check if action.due_date
<= now
do something
I tried:
SELECT o.status, ac.* FROM (
SELECT *
FROM "actions" AS "actions"
WHERE "actions"."status" IN ( 'new', 'processing' )
ORDER BY CASE
WHEN ( "status" = 'processing' ) THEN 0
WHEN( "status" = 'new' ) THEN 1
ELSE 2
END ASC,
CASE
WHEN ( "direction" = 'out' ) THEN 0
WHEN( "direction" = 'in' ) THEN 1
ELSE 2
END ASC,
"actions"."id" ASC
LIMIT 1) AS ac
INNER JOIN orders o on o.id = ac.order_id
where ac.due_date <= ${now}
AND o.status = 'new'
and:
SELECT * FROM orders as o
INNER JOIN (
SELECT *
FROM "actions" AS "actions"
WHERE "actions"."status" IN ( 'new', 'processing' )
ORDER BY CASE
WHEN ( "status" = 'processing' ) THEN 0
WHEN( "status" = 'new' ) THEN 1
ELSE 2
END ASC,
CASE
WHEN ( "direction" = 'out' ) THEN 0
WHEN( "direction" = 'in' ) THEN 1
ELSE 2
END ASC,
"actions"."id" ASC
LIMIT 1) a on a.order_id = o.id AND a.due_date <= ${now}
where o.status = 'new'
Ex of data and required response:
Order table
id status
1 new
2 new
Actions table:
id order_id status direction due_date
1 1 success out now-1
2 1 processing in now+1
3 1 new out now-1
4 2 success out now-1
5 2 new in now-1
6 2 closed out now-1
Response:
id order_id status direction due_date
5 2 new in now-1
Order id 1 is not present because action id 2 due_date
> now
and other actions need to wait until this action will be treated.
Ps. Actions table is smaller, I think to start the select from actions for the selection to be faster / optimized
Thanks in advance
Edit
Added sqlfiddle
Best Answer
Here is one idea using LATERAL:
The semantic is slightly different compared with your query that I rearranged.