Oracle vs MS SQL UPDATE using IN SELECT - sql

This SQL works fine on MS SQL Server but produces an error "ORA-00907: missing right parenthesis".
SQL:
UPDATE DELIVERY
SET VISIBLE = 0
WHERE DELIVERY.ID
IN
(
SELECT DELIVERY.ID FROM delivery WHERE DELIVERY.VISIBLE = 1
EXCEPT
SELECT DELIVERY.ID FROM delivery LEFT JOIN inventory ON INVENTORY.DELIVERYID = DELIVERY.ID
WHERE ((DELIVERY.VISIBLE = 1) AND (INVENTORY.VISIBLE = 1)) AND (INVENTORY.INVENTORYSTATE = 3)
);
Is there a way to get this to work on Oracle or is an UPDATE using an IN with SELECT statements just conceptually wrong?

In Oracle, IN Can also work, just change the EXCEPT to MINUS in Oracle
http://www.techonthenet.com/sql/update.php
http://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_10007.htm
http://docs.oracle.com/cd/E17952_01/refman-5.0-en/exists-and-not-exists-subqueries.html
An Sample Example for this will be
UPDATE DELIVERY
SET VISIBLE = 0
WHERE DELIVERY.ID
IN
(
(SELECT DELIVERY.ID FROM delivery WHERE DELIVERY.VISIBLE = 1)
MINUS
(SELECT DELIVERY.ID
FROM delivery LEFT JOIN inventory ON INVENTORY.DELIVERYID = DELIVERY.ID
WHERE (((DELIVERY.VISIBLE = 1) AND (INVENTORY.VISIBLE = 1))
AND (INVENTORY.INVENTORYSTATE = 3)))
);

I think you can modify this query so that it works in both SQL Server and Oracle:
UPDATE delivery d
SET d.visible = 0
WHERE d.visible = 1
AND NOT EXISTS ( SELECT 1 FROM inventory i
WHERE i.deliveryid = d.id
AND i.visible = 1
AND i.inventorystate = 3 )
This will update DELIVERY setting visible = 0 wherever visible = 1 but there is no corresponding record in INVENTORY with visible = 1 and inventorystate = 3.

Related

How to Combine two queries into one in Oracle SQL

We have an error in production, luckily have a manual solution for this, however I have to run below two queries every morning to fix the error. This is so manual, I want to automate this and combine two queries into one. However we only have this error in production and not in DEV or QA, if I mess up with the combining query that will end up a chaos, So I need your expertise.
1st Query brings project numbers
select id, ugenProjectNumber
from unifier_uxpecai
where (pecaiChecklistNumber = 0 or pecaiChecklistNumber is null)
or (pecaiChecklistItemNumber = 0 or pecaiChecklistItemNumber is null)
2nd Query fix broken links between action items and list items, I manually put 1st query results unique project numbers into second query and run the second query per each unique project numbers.
update unifier_uxpecai pai
set (pai.pecaiChecklistNumber, pai.pecaiChecklistItemNumber) =
(
select pcl.id, pcli.id
from unifier_uxpecl pcl
inner join unifier_uxpecl_lineitem pcli on pcli.uuu_tab_id = 0 and
pcli.record_id = pcl.id
where pcl.ugenProjectNumber = 'GL-16-161010-143502'
and pcli.pecItemActionItemBPC = pai.id
)
where exists
(
select pcli.pecItemActionItemBPC
from unifier_uxpecl pcl
inner join unifier_uxpecl_lineitem pcli on pcli.uuu_tab_id = 0 and
pcli.record_id = pcl.id
where pcl.ugenProjectNumber = 'GL-16-161010-143502'
and pcli.pecItemActionItemBPC = pai.id
)
and (pai.pecaiChecklistNumber = 0 or pai.pecaiChecklistItemNumber = 0)
You can incorporate the logic into the queries:
update unifier_uxpecai pai
set (pai.pecaiChecklistNumber, pai.pecaiChecklistItemNumber) =
(select pcl.id, pcli.id
from unifier_uxpecl pcl join
unifier_uxpecl_lineitem pcli
on pcli.uuu_tab_id = 0 and pcli.record_id = pcl.id
where pcl.ugenProjectNumber in (select ugenProjectNumber
from unifier_uxpecai
where (pecaiChecklistNumber = 0 or pecaiChecklistNumber is null) or
(pecaiChecklistItemNumber = 0 or pecaiChecklistItemNumber is null
) and
pcli.pecItemActionItemBPC = pai.id
)
where exists
(
select pcli.pecItemActionItemBPC
from unifier_uxpecl pcl join
unifier_uxpecl_lineitem pcli
on pcli.uuu_tab_id = 0 and
pcli.record_id = pcl.id
where pcl.ugenProjectNumber in (select ugenProjectNumber
from unifier_uxpecai
where (pecaiChecklistNumber = 0 or pecaiChecklistNumber is null) or
(pecaiChecklistItemNumber = 0 or pecaiChecklistItemNumber is null
) and
pcli.pecItemActionItemBPC = pai.id
) and
(pai.pecaiChecklistNumber = 0 or pai.pecaiChecklistItemNumber = 0)

SQL Server Update from group by

I need to update the column of a temp table from the count of a field from another table. I was trying to do this with the following query, but I get a syntax error.
How should I write this query?
Thanks!
UPDATE #ResultadosTest
SET PalletsReservados = COUNT(pe.paen_numero)
FROM #ResultadosTest RT, dba.spro_palletencab pe
WHERE pe.pate_tempor = RT.pate_tempor
AND pe.expo_codigo = RT.expo_codigo
AND pe.WeekLinId = RT.WeekLinId
AND pe.plde_codigo = RT.plde_codigo
AND pe.paen_estado = 1
AND ISNULL(pe.LoteCargaId, 0) <> 0
AND ISNULL(pe.PREMOPID, 0) <> 0
GROUP BY
pe.pate_tempor, pe.expo_codigo, pe.WeekLinId, pe.plde_codigo
The error is:
Line 10, Incorrect syntax near the keyword 'GROUP' (42000,156)
You can't directly use an aggregate function at update statement. Instead you can you a derived table
Update #ResultadosTest
SET PalletsReservados = ppp.countpaen_numero
From (Select Count(pe.paen_numero) as countpaen_numero ,pe.pate_tempor,spro_palletencab,........
FROM #ResultadosTest RT,dba.spro_palletencab pe
Where pe.pate_tempor=RT.pate_tempor
AND pe.expo_codigo=RT.expo_codigo
AND pe.WeekLinId=RT.WeekLinId
AND pe.plde_codigo=RT.plde_codigo
AND pe.paen_estado=1 AND IsNull(pe.LoteCargaId,0)<>0 AND IsNull(pe.PREMOPID,0)<>0
GROUP BY pe.pate_tempor,pe.expo_codigo,pe.WeekLinId,pe.plde_codigo ) ppp
Where ppp.pate_tempor = Field..
First group, then join
Update #ResultadosTest
SET PalletsReservados = pe.Cnt
FROM #ResultadosTest RT
JOIN (
SELECT pate_tempor, expo_codigo, WeekLinId, plde_codigo, Count(pe.paen_numero) cnt
FROM dba.spro_palletencab pe
WHERE paen_estado=1 AND IsNull(LoteCargaId,0)<>0 AND IsNull(PREMOPID,0)<>0
GROUP BY pate_tempor,expo_codigo,WeekLinId,plde_codigo
) pe ON pe.pate_tempor=RT.pate_tempor
AND pe.expo_codigo=RT.expo_codigo
AND pe.WeekLinId=RT.WeekLinId
AND pe.plde_codigo=RT.plde_codigo;
should work like:
UPDATE RT
SET PalletsReservados = pe.ctr
FROM #ResultadosTest RT
INNER JOIN
(
SELECT pate_tempor
,expo_codigo
,WeekLinId
,plde_codigo
,Count(pe.paen_numero) as ctr
FROM dba.spro_palletencab
WHERE paen_estado = 1
AND ISNULL(LoteCargaId,0) <> 0
AND ISNULL(PREMOPID,0) <> 0
GROUP BY pe.pate_tempor
,pe.expo_codigo
,pe.WeekLinId
,pe.plde_codigo
) pe
ON pe.pate_tempor = RT.pate_tempor
AND pe.expo_codigo = RT.expo_codigo
AND pe.WeekLinId = RT.WeekLinId
AND pe.plde_codigo = RT.plde_codigo

Not able to optimize a SQL Query. Taking huge cost. Oracle Apps

This is a query which I have to use as part of extracting Receipts based on certain conditions from Oracle 11i as a part of Conversion.
--> One important check is to check for invoices on hold. I just need to pull the details wherein the invoices are on hold. And the condition for checking is
In AP_HOLDS_ALL table -- 1) the invoice should exist
2) release lookup code should be NULL
3) status flag should be S or NULL and
4) there should not exist any line in AP_HOLDS_ALL table with same invoice ID with release lookup code as not null.
I have tried and added the below criteria in last of the following query, but it fetches the rows very very slow (100 000 records in a day).
How to improve the performance?
select * -- multiple Columns
from rcv_shipment_headers rsh,
rcv_shipment_lines rsl,
rcv_transactions rt,
hr_operating_units hou,
po_headers_all poh,
po_lines_all pol,
po_line_locations_all pll,
po_distributions_all pda,
po_vendors pv,
po_vendor_sites_all pvs
where 1 = 1
and rsh.shipment_header_id = rsl.shipment_header_id
and rsh.shipment_header_id = rt.shipment_header_id
and rsl.shipment_line_id = rt.shipment_line_id
and rt.po_header_id = poh.po_header_id
and rt.po_line_id = pol.po_line_id
and rt.po_line_location_id = pll.line_location_id
and rt.po_distribution_id = pda.po_distribution_id
and poh.po_header_id = pol.po_header_id
and pol.po_line_id = pll.po_line_id
and pll.line_location_id = pda.line_location_id
and poh.org_id = hou.organization_id
and poh.type_lookup_code = 'STANDARD'
and poh.authorization_status = 'APPROVED'
and poh.approved_flag = 'Y'
and rsh.ship_to_org_id = pll.ship_to_organization_id
and rt.organization_id = pll.ship_to_organization_id
and pol.org_id = hou.organization_id
and pll.org_id = hou.organization_id
and pda.org_id = hou.organization_id
and hou.date_to is null
and (rt.transaction_type = 'DELIVER' or rt.transaction_type = 'RECEIVE')
and rt.vendor_site_id = pvs.vendor_site_id
and rt.vendor_id = pv.vendor_id
and pv.vendor_id = pvs.vendor_id
and (nvl(pda.quantity_ordered, 0) - nvl(pda.quantity_cancelled, 0)) > 0
and nvl(pda.quantity_delivered, 0) > 0
and nvl(pda.quantity_billed, 0) > 0
and nvl(rsl.quantity_received, 0) > 0
and ((nvl(pda.quantity_delivered, 0) = nvl(pda.quantity_billed, 0)) or
(nvl(pda.quantity_delivered, 0) > nvl(pda.quantity_billed, 0)) or
(nvl(pda.quantity_delivered, 0) < nvl(pda.quantity_billed, 0)))
and exists
(select aida.po_distribution_id
from ap_invoices_all aia, ap_invoice_distributions_all aida
where aia.cancelled_date is null
and aida.po_distribution_id = pda.po_distribution_id
and exists
(select c.invoice_id
from ap_holds_all c
where c.release_lookup_code is null
and c.invoice_id = aia.invoice_id
and c.org_id = nvl(p_leg_operating_unit, c.org_id)
and (c.status_flag = 'S' or c.status_flag is null)
and not exists
(select 1
from ap_holds_all d
where d.invoice_id = c.invoice_id
and d.org_id = nvl(p_leg_operating_unit, d.org_id)
and d.release_lookup_code is not null))
and aia.org_id = nvl(p_leg_operating_unit, aia.org_id)
and aia.invoice_id = aida.invoice_id)
and poh.org_id = nvl(p_leg_operating_unit, poh.org_id)
p_leg_operating_unit is a parameter which is having NULL value as I am trying to get the values for all the OU's
** last exists is causing the issue.
Try with the following , may solve your issue :
/*+ parallel(4) */ --hint. If doesnt work , then try with
parallel(8)/parallel(16).
Reorder the joins . Join the tables based on the least number of rows returned. FOr example Table A,B,C . Join a & b returns 100
rows, but B&c returns 20 rows. then First join B & C table and join
with A.
Use /*+ Index * hint if optimizer doesn't access indexes.

SQL Load Fact with Merge Statement Slow

I'm loading a fact table using MERGE and it's taking 44 minutes for 1 million records. Is there a way I can improve this?
My query:
MERGE INTO dbo.FactProjMarketCode AS target
USING (
SELECT
SourceSystem = 'ORACLE_ERP',
ProjMarketCodeSourceId = jmc.XT_JOB_MARKETING_CODE_ID,
p.ProjectId,
MarketCodeId = ISNULL(mc.MarketingCodeId,-1),
Weight = 0.01 * ISNULL(jmc.WEIGHT,100),
WasMissing = CASE WHEN jmc.WEIGHT IS NULL THEN 1 ELSE 0 END,
jmc.LAST_UPDATE_DATE
FROM
dimProject p
LEFT JOIN stage.XT_JOB_MARKETING_CODE jmc
ON p.ProjectSourceId = jmc.XT_PROJECT_ID
LEFT JOIN DimMarketingCode mc
ON jmc.MARKETING_CODE = mc.MarketingCode -- should create column MarketingCodeSourceId
AND mc.SourceSystem = 'ORACLE_ERP'
WHERE
p.SourceSystem = 'ORACLE_ERP'
) AS source
ON target.SourceSystem = source.SourceSystem
AND target.ProjMarketCodeSourceId = source.ProjMarketCodeSourceId
WHEN MATCHED AND source.LAST_UPDATE_DATE > target.LAST_UPDATE_DATE
THEN UPDATE SET
target.ProjectId = source.ProjectId,
target.MarketCodeId = source.MarketCodeId,
target.Weight = source.WEIGHT,
target.WasMissing = source.WasMissing,
target.LAST_UPDATE_DATE = source.LAST_UPDATE_DATE
WHEN NOT MATCHED BY target
THEN INSERT (
SourceSystem,
ProjMarketCodeSourceId,
ProjectId,
MarketCodeId,
Weight,
WasMissing,
LAST_UPDATE_DATE
) VALUES (
source.SourceSystem,
source.ProjMarketCodeSourceId,
source.ProjectId,
source.MarketCodeId,
source.Weight,
source.WasMissing,
source.LAST_UPDATE_DATE
)
WHEN NOT MATCHED BY source
THEN DELETE;

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
);