Sql query taking forever to execute - sql

Following is query that i am trying to execute and it is taking forever to execute.
SELECT DISTINCT (CLN_CLNDR_DT)FROM CLN_CLNDR CLN,
SYG_SYSTEM_GLOBALS SYG,CTD_CSH_TRNSCTN_DTLS CTD WHERE CLN.CLN_BP_ID = SYG.SYG_BP_ID AND CLN.CLN_ENTITY_ID = CTD.CTD_ENTITY_ID AND CLN_DT_SEQ_NUM
IN
(SELECT DISTINCT (CLN1.CLN_DT_SEQ_NUM)
FROM CLN_CLNDR CLN1,
SBD_SYS_BSNS_DTS SBD,
SYG_SYSTEM_GLOBALS SYG,
CTD_CSH_TRNSCTN_DTLS CTR
WHERE SBD.SBD_BSNS_DT = CLN1.CLN_CLNDR_DT
AND CLN1.OU_ID = SBD.OU_ID
AND CLN1.CLN_BP_ID = SYG.SYG_BP_ID
AND CLN1.CLN_ENTITY_ID = CTR.CTD_ENTITY_ID
);
When i try to run just the query inside in , it easily returns result as
(522,470,419,417,553,582,305,361)
SELECT DISTINCT (CLN1.CLN_DT_SEQ_NUM)
FROM CLN_CLNDR CLN1,
SBD_SYS_BSNS_DTS SBD,
SYG_SYSTEM_GLOBALS SYG,
CTD_CSH_TRNSCTN_DTLS CTR
WHERE SBD.SBD_BSNS_DT = CLN1.CLN_CLNDR_DT
AND CLN1.OU_ID = SBD.OU_ID
AND CLN1.CLN_BP_ID = SYG.SYG_BP_ID
AND CLN1.CLN_ENTITY_ID = CTR.CTD_ENTITY_ID;
Also when i try to execute directly the full query replacing the query inside in block
with the result of inner query that is (522,470,419,417,553,582,305,361),
It is working fine.
As i am new to this , i don't know what is going on .
Please help me with this.

I don't think you need all the tables in the subquery since you are already using them to filter rows in the outer query. Try this:
SELECT DISTINCT (CLN_CLNDR_DT)
FROM CLN_CLNDR CLN,
SYG_SYSTEM_GLOBALS SYG,
CTD_CSH_TRNSCTN_DTLS CTD
WHERE CLN.CLN_BP_ID = SYG.SYG_BP_ID
AND CLN.CLN_ENTITY_ID = CTD.CTD_ENTITY_ID
AND CLN_DT_SEQ_NUM
IN
(SELECT DISTINCT (CLN1.CLN_DT_SEQ_NUM)
FROM CLN_CLNDR CLN1,
SBD_SYS_BSNS_DTS SBD,
WHERE SBD.SBD_BSNS_DT = CLN1.CLN_CLNDR_DT
AND CLN1.OU_ID = SBD.OU_ID
);

Related

Optimize many subqueries with same source

Does anyone have any idea how to optimize such a query?
How do you encapsulate this into one query?
,(SELECT top 1 WFD_AttDecimal2 as Nocleg
FROM WFElements INNER JOIN
WFElementDetails ON WFElements.WFD_ID = WFElementDetails.DET_WFDID
Where
WFD_STPID = #KrokSlownikUdostepnionyKraj
and dbo.ClearWFElemID (WFD_AttChoose20) = KrajDoDiety6 -- id kraju
and dbo.ClearWFElemID (WFD_AttChoose9) = #Spolka) as NoclegStawka7
,(SELECT top 1 WFD_AttDecimal3 as NoclegPrzelicznik
FROM WFElements INNER JOIN
WFElementDetails ON WFElements.WFD_ID = WFElementDetails.DET_WFDID
Where
WFD_STPID = #KrokSlownikUdostepnionyKraj
and dbo.ClearWFElemID (WFD_AttChoose20) = KrajDoDiety6 -- id kraju
and dbo.ClearWFElemID (WFD_AttChoose9) = #Spolka) as NoclegPrzelicznik7
,PelneDoby6 * (select MinDieta from #MinDieta where RodzajDelegacji = KrajZagr6) as MinIloscDiet7
from #Dieta4
You can use OUTER APPLY or CROSS APPLY and select all the necessary columns within that, you can then access all of them in the SELECT
SELECT
wfd.Nocleg as NoclegStawka7
, wfd.NoclegPrzelicznik as NoclegPrzelicznik7
, d.PelneDoby6 * (select md.MinDieta from #MinDieta md where RodzajDelegacji = KrajZagr6) as MinIloscDiet7
from #Dieta4 d
OUTER APPLY (
SELECT TOP (1)
WFD_AttDecimal2 as Nocleg,
WFD_AttDecimal3 as NoclegPrzelicznik
FROM WFElements INNER JOIN
WFElementDetails ON WFElements.WFD_ID = WFElementDetails.DET_WFDID
Where
WFD_STPID = #KrokSlownikUdostepnionyKraj
and dbo.ClearWFElemID (WFD_AttChoose20) = KrajDoDiety6 -- id kraju
and dbo.ClearWFElemID (WFD_AttChoose9) = #Spolka
) wfd;
Note also:
I suggest you rethink your usage of a scalar function ClearWFElemID as it can be slow. Use a join or a Table Valued function instead.
TOP (1) without an ORDER BY is a code-smell: you may get a different result each time.
Always specify the table alias when using subqueries, or you risk getting the wrong results.

Comparing Query Result With Table and Retrieve Specific Field

My Query
SELECT
stoMast.sStockistCode,
stoMast.sStateName,
stoMast.sDivision,
stateMap.sRMCode
FROM
tblRSM_State_Mapping stateMap
INNER JOIN
tblStockistMaster stoMast ON
stateMap.sStateName = stoMast.sStateName
WHERE
stateMap.sRMCode = 'MCNE04001'
and
stoMast.sDivision = 'CIDIS'
except
select
sStockistCode,
sStateName,
sDivision,
sRMCode
From
tblEntry
Again I would like to compare the query result columns
sStockistCode
sStateName
sDivision
with tblStockistMaster with the same fields
sStockistCode
sStateName
sDivision
and retrieve the STOCKIST NAME.
Don't know how to compare the above query result with the table.
Maybe you can use following SQL code used with CTE expression
;with cte as (
SELECT
stoMast.sStockistCode,
stoMast.sStateName,
stoMast.sDivision,
stateMap.sRMCode
FROM
tblRSM_State_Mapping stateMap
INNER JOIN
tblStockistMaster stoMast ON
stateMap.sStateName = stoMast.sStateName
WHERE
stateMap.sRMCode = 'MCNE04001'
and
stoMast.sDivision = 'CIDIS'
except
select
sStockistCode,
sStateName,
sDivision,
sRMCode
From
tblEntry
)
select
cte.*,
sm.sStockistName
from cte
left join tblStockistMaster as sm
on sm.sStockistCode = cte.sStockistCode and
sm.sStateName = cte.sStateName and
sm.sDivision = cte.sDivision
-- I retrieve the stockist Name
SELECT
stoMast.sStockistName,
FROM
tblRSM_State_Mapping stateMap
INNER JOIN
tblStockistMaster stoMast
ON stateMap.sStateName = stoMast.sStateName
-- I'm joining table entry If I can match
LEFT JOIN
tblEntry tbl
on tbl.sStockistCode = stoMast.sStockistName
AND tbl.sStateName = stoMast.sStateName
AND tbl.sDivision = stoMast.sDivision
AND tbl.sRMCode = stateMap.sRMCode
WHERE
stateMap.sRMCode = 'MCNE04001'
and stoMast.sDivision = 'CIDIS'
-- And The the exept thing, I don't want that got a match with the tableentry
AND COALESCE(tbl.sStockistCode, tbl.sStateName, tbl.sDivision, tbl.sRMCode) is null
I expect it is what you wanted to get. On another way please help us understand wht you come from (tables and idea of what data can be in) and the result you want. Will be easier to create a query.

Use alias for JOIN using JOOQ's SelectQuery

I need to write query with nested select and join using JOOQ's SelectQuery:
SELECT *
FROM (select * from
"public"."parent"
order by "public"."parent"."setup_time"
desc limit 10 offset 0) as "parent1"
join "public"."child"
on "public"."child"."parent_id" = "parent1"."id"
where "public"."child"."name" = 'test'
So, I've written something like this:
SelectQuery<ParentRecord> subSelectQuery = context.selectQuery(PARENT);
selectQuery.addJoinOnKey(CHILD, JoinType.JOIN, CHILD.PARENT_ID);
But it generates sql code like
join "public"."child" on "public"."child"."parent_id" = "public"."parent"."id
How can I use alias parent1 instead of full table name "public"."child"."parent_id"?
I've found solution.
SelectQuery<ParentRecord> selectQuery = context.selectQuery(subSelectQuery.asTable(PARENT.getName()));
selectQuery.addJoin(CHILD, JoinType.JOIN, CHILD.PARENT_ID.eq(PARENT.as(PARENT.getName()).ID));

SQL select query in update

I am trying to fix this query:
I have an update query.
UPDATE controll_SZHEAD14
LEFT JOIN [outgoing] ON controll_SZHEAD14.sa_code = [outgoing].Account
SET [outgoing].Account = controll_SZHEAD14.sa_code, [outgoing].Buyer = controll_SZHEAD14.sa_buyername, [outgoing].startdate = controll_SZHEAD14.sa_date, [outgoing].Finance = controll_SZHEAD14.sa_tedat, [outgoing].maxdate = controll_SZHEAD14.sa_esdat, [outgoing].[25alap] = controll_SZHEAD14.sa_summary
WHERE (((controll_SZHEAD14.sa_code)>"BA14/01997"));
So if I run this query above, than refresh my data, but only from BA14/01997 till now. So in this example this will refresh 66 row. (66 row affected)
I have this simple select SQL:
SELECT TOP 1 Account FROM [outgoing] ORDER BY Account DESC;
If I run this above I got the last account, in this example:BA14/01997
So I would like to take this two query "update+select" together.
UPDATE controll_SZHEAD14
LEFT JOIN [outgoing] ON controll_SZHEAD14.sa_code = [outgoing].Account
SET [outgoing].Account = controll_SZHEAD14.sa_code, [outgoing].Buyer = controll_SZHEAD14.sa_buyername, [outgoing].startdate = controll_SZHEAD14.sa_date, [outgoing].Finance = controll_SZHEAD14.sa_tedat, [outgoing].maxdate = controll_SZHEAD14.sa_esdat, [outgoing].[25alap] = controll_SZHEAD14.sa_summary
WHERE (((controll_SZHEAD14.sa_code)>"SELECT TOP 1 Account FROM [outgoing] GROUP BY Account DESC;"));
The above query does not work properly. When I run, I got 0 row affected, but I expect the same as the first update query.
Any idea how to fix this?
Enclose the SELECT statement in ( ) brackets
UPDATE controll_SZHEAD14
LEFT JOIN [outgoing]
ON controll_SZHEAD14.sa_code = [outgoing].Account
SET [outgoing].Account = controll_SZHEAD14.sa_code,
[outgoing].Buyer = controll_SZHEAD14.sa_buyername,
[outgoing].startdate = controll_SZHEAD14.sa_date,
[outgoing].Finance = controll_SZHEAD14.sa_tedat,
[outgoing].maxdate = controll_SZHEAD14.sa_esdat,
[outgoing].[25alap] = controll_SZHEAD14.sa_summary
WHERE controll_SZHEAD14.sa_code > (
SELECT TOP 1 Account
FROM [outgoing]
ORDER BY Account DESC
);

Subquery return more than one value

I have the following query which gives gives req_no and order_no. order_no is a from a sub_query which you can see from below sql. For a few req_no there are more than one order_no's and because of that I get ORA-01427: single-row subquery returns more than one row.
I would like to display both the order_no for one req_no, how can I achieve this?
Any help is highly appreciable.
Thanks
P.S. Our client's one database is still Oracle 8i.
SELECT max_qst.req_no,
(SELECT DISTINCT max_odr.order_no
FROM maximo_orders max_odr,
maximo_order_revisions max_odv,
maximo_order_items max_odi,
maximo_order_dates max_odd,
maximo_requisition_order max_rqo,
maximo_requisition_details max_req
WHERE max_req.req_no = max_qst.req_no
AND max_req.req_yr = max_qst.req_yr
AND max_odr.order_no = max_odi.order_no
AND max_odi.order_item_id = max_odd.order_item_id
AND max_req.requisition_item_id = max_rqo.requisition_item_id
AND max_rqo.order_schedule_id = max_odd.order_schedule_id
AND max_odv.order_no = max_odi.order_no
AND max_odv.revision_no =
(SELECT MAX (max_alias.revision_no)
FROM maximo_order_revisions max_alias
WHERE max_alias.order_no = max_odv.order_no)
AND maximo_order_item (max_odi.order_no,
max_odv.revision_no,
max_odi.order_item_id
) = 'CONFIRMED'
)
FROM maximo_requisitions max_qst, maximo_requisition_details max_qsd
WHERE max_qst.qst_id = max_qsd.qst_id
AND max_qst.enter_date = '2001'
AND max_qst.req_no = 'PUR_12WX'
Update 1
Desired out put.
REQ_No ORDER_NO
PUR_12WX PR_9078
PUR_12WX PR_9079
Use a join instead of a correlated sub-query.
I've removed the max_qst references from the sub-query and moved them to the join predicate.
I've also just changed it to use a LEFT JOIN. This allows for the possibility of there being no order_no values returned.
SELECT
max_qst.req_no,
sub_query.order_no
FROM
maximo_requisitions max_qst
INNER JOIN
maximo_requisition_details max_qsd
ON max_qst.qst_id = max_qsd.qst_id
LEFT JOIN
(
SELECT DISTINCT
max_odr.order_no,
max_req.req_no,
max_req.req_yr
FROM
maximo_orders max_odr,
maximo_order_revisions max_odv,
maximo_order_items max_odi,
maximo_order_dates max_odd,
maximo_requisition_order max_rqo,
maximo_requisition_details max_req
WHERE
max_odr.order_no = max_odi.order_no
AND max_odi.order_item_id = max_odd.order_item_id
AND max_req.requisition_item_id = max_rqo.requisition_item_id
AND max_rqo.order_schedule_id = max_odd.order_schedule_id
AND max_odv.order_no = max_odi.order_no
AND max_odv.revision_no = (SELECT MAX (max_alias.revision_no)
FROM maximo_order_revisions max_alias
WHERE max_alias.order_no = max_odv.order_no)
AND maximo_order_item (max_odi.order_no, max_odv.revision_no, max_odi.order_item_id) = 'CONFIRMED'
)
suq_query
ON max_qst.req_no = sub_query.req_no
AND max_qst.req_yr = sub_query.req_yr
WHERE
max_qst.enter_date = '2001'
max_qst.req_no = 'PUR_12WX'
You can use
DISTINCT
or
WHERE ROWNUM = 1
But I'd suggest you investigate why you're getting more than one row returned: Have you misunderstood the data, have you missed a join, is there erroneous or duplicate data etc etc.