Oracle SQL - WHERE Clause - sql

I'm new here so forgive me if this could be worded better.
I need to return details for any people who are either:
Grade 'C' and salary not equal to 9.00
or
Grade 'D' and salary not equals 9.75
E.g.
SELECT
paam.ASSIGNMENT_NUMBER,
cs.SALARY_AMOUNT,
pgf.NAME Grade
FROM
CMP_SALARY cs,
PER_ALL_ASSIGNMENTS_M paam,
PER_GRADES_F_TL pgf
WHERE
pgf.GRADE_ID = paam.GRADE_ID
AND cs.ASSIGNMENT_ID = paam.ASSIGNMENT_ID
AND (pgf.name = 'C' AND cs.SALARY_AMOUNT <> '9.00')
or (pgf.name = 'D' AND cs.SALARY_AMOUNT <> '9.75')
Any help you can give will be much appreciated. :)

The problem is logical prescendence. or has lower priority than and, so you need to surround the entire or conditions with parentheses.
So basically change this:
WHERE
pgf.GRADE_ID = paam.GRADE_ID
AND cs.ASSIGNMENT_ID = paam.ASSIGNMENT_ID
AND (pgf.name = 'C' AND cs.SALARY_AMOUNT <> '9.00')
OR (pgf.name = 'D' AND cs.SALARY_AMOUNT <> '9.75')
To:
WHERE
pgf.GRADE_ID = paam.GRADE_ID
AND cs.ASSIGNMENT_ID = paam.ASSIGNMENT_ID
AND (
(pgf.name = 'C' AND cs.SALARY_AMOUNT <> '9.00')
OR (pgf.name = 'D' AND cs.SALARY_AMOUNT <> '9.75')
)
The inner parentheses are not strictly needed (for the afformentioned reasons), but they make the intent clearer.
I would also recommend rewriting the query to use standard, explicit joins, rather than old-school, implicit joins. Incidently, this takes away the prescendence issue:
SELECT
paam.ASSIGNMENT_NUMBER,
cs.SALARY_AMOUNT,
pgf.NAME Grade
FROM CMP_SALARY cs
INNER JOIN PER_ALL_ASSIGNMENTS_M paam
ON cs.ASSIGNMENT_ID = paam.ASSIGNMENT_ID
INNER JOIN PER_GRADES_F_TL pgf
ON pgf.GRADE_ID = paam.GRADE_ID
WHERE
(pgf.name = 'C' AND cs.SALARY_AMOUNT <> '9.00')
OR (pgf.name = 'D' AND cs.SALARY_AMOUNT <> '9.75')

Related

Oracle SQL Case When Missing right parenthesis [duplicate]

This question already has answers here:
0RA-00907: SQL MISSING RIGHT PARENTHESIS
(1 answer)
SQL Missing right parenthesis on order by statement
(2 answers)
Closed 7 days ago.
I have this query where it selects different columns based on condition case when, I'm trying to make it work since long time but i dont know what is going on with damned case when, it just keep saying missing right parenthesis forever!!! plz help !!
no need to add any other code, if i remove the case when query works fine.
SELECT ...,
( case when PERSON_TYPE_ID= '300000000326669' then (select round(prvf.value,2)
FROM fusion.per_rates_f prf,
fusion.per_rate_values_f prvf,
fusion.per_assign_grade_steps_f pagsf,
fusion.per_all_assignments_m paam
WHERE prf.rate_id = prvf.rate_id
AND prf.rate_object_type = 'STEP'
AND prf.grade_ladder_id = paam.grade_ladder_pgm_id
AND TRUNC(cgpi.effective_date) BETWEEN prf.effective_start_date AND
prf.effective_end_date
AND prvf.rate_object_type = 'STEP'
AND TRUNC(cgpi.effective_date) BETWEEN prvf.effective_start_date AND
prvf.effective_end_date
AND pagsf.grade_step_id = prvf.rate_object_id
AND (cgpi.effective_date) BETWEEN pagsf.effective_start_date AND
pagsf.effective_end_date
AND pagsf.assignment_id = paam.assignment_id
AND paam.assignment_type = 'E'
AND PAAM.EFFECTIVE_LATEST_CHANGE = 'Y'
AND PAAM.Assignment_Status_Type = 'ACTIVE'
AND paam.person_id = papf.person_id
and papf.person_id = A.person_id
AND trunc(cgpi.effective_date) BETWEEN paam.effective_start_date AND
paam.effective_end_date
order by pagsf.effective_start_date desc
)
When PERSON_TYPE_ID ='300000001851545' then (select PPG.SEGMENT1
from FUSION.PER_ALL_ASSIGNMENTS_M paam,
FUSION.PER_PEOPLE_GROUPS PPG
WHERE 1 = 1
AND PAAM.PERSON_ID = papf.person_id
AND PAAM.ASSIGNMENT_TYPE = 'E'
AND PAAM.PRIMARY_ASSIGNMENT_FLAG = 'Y'
AND TRUNC(cgpi.effective_date) BETWEEN PAAM.EFFECTIVE_START_DATE AND
PAAM.EFFECTIVE_END_DATE
AND PAAM.ASSIGNMENT_STATUS_TYPE = 'ACTIVE'
and paam.people_group_id = ppg.people_group_id
and papf.person_id = A.person_id
AND PAAM.PERIOD_OF_SERVICE_ID =
(SELECT MAX(PPOS.PERIOD_OF_SERVICE_ID)
FROM FUSION.PER_PERIODS_OF_SERVICE PPOS
WHERE PPOS.PERSON_ID = PAAM.PERSON_ID
and ppos.date_start <= trunc(cgpi.effective_date)
and ppos.actual_termination_date =A.actual_termination_date
))
end
) Basic_Sal

Any alternate of REGEXP_LIKE as it causing performance issue

We have one sql which is performing bad.I have fixed the execution plan but REGEXP_LIKE causing high buffer gets and also contribute in runtime.Any alternate which i can use in my sql.The problematc is
AND REGEXP_LIKE (xx3la.assembly_type, '^I..*')
/* Formatted on 1/6/2023 2:07:28 PM (QP5 v5.318) */
SELECT 1
FROM apps.oe_order_lines_all ola
JOIN APPS.OE_order_headers_all oh
ON oh.Header_Id = ola.header_id AND oh.org_id = ola.org_id
JOIN inv.mtl_parameters org
ON ola.ship_from_org_id = org.ORGANIZATION_ID
INNER JOIN ont.oe_transaction_types_tl tt
ON tt.transaction_type_id = oh.order_type_id
AND tt.language = 'US'
AND LPAD (UPPER (tt.name), 4) NOT IN ('TRIA',
'WARR',
'REPA',
'DUMM',
'DEMO',
'GOOD',
'INTE',
'CRED',
'EVAL',
'INVO') --- ('STAND')
JOIN apps.mtl_system_items_b msib
ON ola.Ordered_item_Id = msib.inventory_item_id
AND msib.ORGANIZATION_ID = org.ORGANIZATION_ID
INNER JOIN xxom.xxom_3lp_sym_ora_order_hdr xx3ha
ON xx3ha.header_id = oh.header_id
INNER JOIN xxom.xxom_3lp_sym_ora_order_lines xx3la
ON xx3la.header_id = ola.header_id AND xx3la.line_id = ola.line_id
LEFT JOIN
(SELECT msib.Inventory_item_id,
mcb.segment1 ProductionLine,
msib.ORGANIZATION_ID,
msib.item_type,
msib.Fixed_LEAD_Time
FROM apps.mtl_system_items_b msib
JOIN inv.mtl_parameters org
ON msib.ORGANIZATION_ID = org.ORGANIZATION_ID
JOIN apps.MTL_ITEM_CATEGORIES ic
ON ic.INVENTORY_ITEM_ID = msib.INVENTORY_ITEM_ID
AND msib.organization_id = ic.ORGANIZATION_ID
JOIN apps.mtl_categories_b mcb
ON mcb.CATEGORY_ID = ic.CATEGORY_ID
WHERE mcb.ENABLED_FLAG = 'Y' AND ic.CATEGORY_SET_ID = 1100009407) im
ON ola.Ordered_item_Id = im.inventory_item_id
AND org.organization_id = im.organization_id
LEFT JOIN ( SELECT Header_Id,
Line_Id,
WIP_ORDER_NUMBER,
MAX (PRODUCT_LINE) PRODUCT_LINE
FROM XXRMT.XXURD_SO_UNIT
GROUP BY Header_Id, Line_Id, WIP_ORDER_NUMBER) u
ON u.Header_Id = oh.Header_Id AND u.Line_Id = ola.Line_Id
LEFT JOIN wip.wip_discrete_jobs wdj
ON wdj.source_line_id = ola.line_id
AND wdj.status_type IN (1,
2,
3,
4,
5,
12)
LEFT JOIN wip.wip_entities we ON we.wip_entity_id = wdj.wip_entity_id
LEFT JOIN xxrmt.xxont_som_scheduler adm
ON adm.subscriber_id = xx3la.order_admin
LEFT JOIN apps.oe_order_lines_all ol2
ON ol2.ato_line_id = ola.line_id
AND ol2.item_type_code IN ('CONFIG')
LEFT JOIN
(SELECT mso.source_organization_code,
mso.vendor_name,
mso.vendor_site,
msa.sourcing_rule_name,
DECODE (mso.source_type,
1, 'TRANSFER',
2, 'MAKE',
3, 'BUY')
SourceType,
msa.inventory_item_id,
msa.organization_id
FROM apps.mrp_sr_assignments_v msa
--join inv.mtl_parameters org on msa.organization_id = org.organization_id
INNER JOIN apps.mrp_sourcing_rules msr
ON msr.sourcing_rule_id = msa.sourcing_rule_id
INNER JOIN apps.mrp_sr_receipt_org_v msro
ON msr.sourcing_rule_id = msro.sourcing_rule_id
INNER JOIN apps.mrp_sr_source_org_v mso
ON mso.sr_receipt_id = msro.sr_receipt_id AND mso.RANK = 1
WHERE msa.assignment_set_id = 561
AND (msro.disable_date IS NULL OR disable_date >= SYSDATE))
srd
ON srd.inventory_item_id = ol2.inventory_item_id
AND srd.organization_id = ola.ship_from_org_id
WHERE org.organization_code IN ('DRM')
AND ola.Flow_Status_Code <> 'CANCELLED'
AND NVL (oh.Cancelled_flag, 'N') = 'N'
AND oh.Flow_Status_Code <> 'CANCELLED'
AND ola.booked_flag = 'Y'
AND oh.booked_date IS NOT NULL
AND TRUNC (oh.booked_date) >= TO_DATE ('2022-12-01', 'YYYY-MM-DD')
AND msib.item_type NOT IN ('P',
'B/R',
'OP',
'SVC',
'OP',
'EMR_PURCH')
AND ( ola.item_type_code IN ('CONFIG', 'MODEL')
OR ( ola.item_type_code IN ('CLASS')
AND REGEXP_LIKE (xx3la.assembly_type, '^I..*'))
OR ( ola.item_type_code IN ('CLASS')
AND u.PRODUCT_LINE IS NOT NULL
AND xx3la.model_string IS NOT NULL
AND msib.segment1 NOT IN ('R-CAP1199', 'R-38-315'))
OR ( ola.item_type_code = 'STANDARD'
AND xx3la.assembly_type IS NULL))
Somehow fixed the BG issue but still REGEXP_LIKE an issue
Your current regex assertion:
REGEXP_LIKE(xx3la.assembly_type, '^I..*')
can be written using an ordinary LIKE:
xx3la.assembly_type LIKE 'I_%'
Note that the above LIKE version should be able to use an index on assembly_type. That being said, I doubt that the REGEXP_LIKE call be the only major performance bottleneck existing in a query of this size and complexity. You should run EXPLAIN on your query to view the execution plan.

How to write SQL query to ignore duplicate row with null value

My View shows Duplicate row which i don't want.
I am geting
1, YM
1, NULL
2, YM
2, NULL
With below Code
SELECT
dbo.Store.SID,
CASE WHEN dbo.Store.SID <> dbo.FileStore.SID THEN NULL
WHEN dbo.FileStore.MailSent = 'M' THEN 'YM'
WHEN dbo.FileStore.SID = dbo.Store.SID AND dbo.FileStore.FileType = 1 THEN 'Y'
ELSE NULL END AS FM
FROM
dbo.STORE
INNER JOIN dbo.FileStore ON dbo.Store.SID = dbo.FileStore.SID
I am looking for
1 YM
2 YM
You appear to want filtering. If I understand correctly:
SELECT s.SID,
(CASE WHEN fs.MailSent = 'M' THEN 'YM'
WHEN fs.FileType = 1 THEN 'Y'
END) AS FM
FROM dbo.STORE s INNER JOIN
dbo.FileStore fs
ON s.SID = fs.SID
WHERE fs.MailSent = 'M' OR fs.FileType = 1;
There is no reason to repeat the JOIN conditions in the CASE expression. You know they are true because of the JOIN.
SELECT
dbo.Store.SID
,CASE
WHEN dbo.Store.SID <> dbo.FileStore.SID THEN NULL --will never happen since it's an inner join
WHEN dbo.FileStore.MailSent = 'M' THEN 'YM'
WHEN dbo.FileStore.SID = dbo.Store.SID --will happen always since it's an inner join
AND dbo.FileStore.FileType = 1 THEN 'Y'
ELSE NULL -- this is the cause for Null, you have FileStore.MailSent <> 'M'
END AS FM
FROM dbo.STORE
INNER JOIN dbo.FileStore
ON dbo.Store.SID = dbo.FileStore.SID

The below SQL Query is taking more time and what are all the way to improve the performance?

The below query is taking a lot of time, all the columns are indexed.
What are all the way to optimize it?
SELECT
COUNT(CAST(CA.CORNER_ATTITUDE_ID AS VARCHAR (40)))
FROM
(SELECT *
FROM CORNER_ATTITUDE
WHERE OWNER_ID = '100'
AND CORNER_ATTITUDE_ID NOT IN (SELECT LEGAL_ID
FROM CAPTAIN_LOGIC
WHERE LEGAL_ID != '12345678'
AND OWNER_ID = '100')) CA
LEFT OUTER JOIN
CORNER_ATTITUDE_MEMBER CAC ON (CA.CORNER_ATTITUDE_ID = CAC.CORNER_ATTITUDE_ID)
JOIN
(SELECT *
FROM MEMBER
WHERE MEMBER_ROLE_ID = 'MEMBER') C ON (CAC.MEMBER_FESTIVEL_ID = C.MEMBER_FESTIVEL_ID)
LEFT OUTER JOIN
VINAYAN P ON (C.MEMBER_FESTIVEL_ID = P.VINAYAN_FESTIVEL_ID)
LEFT OUTER JOIN
VINAYAN_NAME PN ON (P.VINAYAN_FESTIVEL_ID = PN.VINAYAN_FESTIVEL_ID)
LEFT OUTER JOIN
DRA_SERVER OC ON CAST (ca.STAR_0_Numer AS NVARCHAR2 (40)) = OC.SERVER_PID
LEFT OUTER JOIN
(SELECT CORNER_ATTITUDE_ID, PROVIDE_ID
FROM STORED_PROVIDE
WHERE PROVIDE_ORIGIN_TYPE_CD = 'PROVIDE_ORIGIN_TYPE_DECISION_SERVICE') CF ON (CA.CORNER_ATTITUDE_ID = CF.CORNER_ATTITUDE_ID)
LEFT OUTER JOIN
STORED_DETAIL CD ON CD.PROVIDE_ID = CF.PROVIDE_ID
LEFT OUTER JOIN
STORED_APPL_PRODUCT CAP ON CAP.STORED_DETAIL_ID = CD.STORED_DETAIL_ID
LEFT OUTER JOIN
PRODUCT_TYPE PT ON PT.PRODUCT_TYPE_CD = CAP.PRODUCT_TYPE_CD
LEFT OUTER JOIN
DRA O ON O.GREEN_FESTIVEL_ID = OC.SERVER_FESTIVEL_ID
WHERE
(CA.STAR_0_STRG = 'TRUE'
AND CA.CORNER_ATTITUDE_STATUS_CD <> 'A'
AND CA.CORNER_ATTITUDE_STATUS_CD <> 'B'
AND CA.CORNER_ATTITUDE_STATUS_CD <> 'C'
AND CA.CORNER_ATTITUDE_STATUS_CD <> 'D'
AND CA.CORNER_ATTITUDE_STATUS_CD <> 'E'
AND CA.CORNER_ATTITUDE_STATUS_CD <> 'F'
AND CA.CORNER_ATTITUDE_STATUS_CD <> 'G'
AND CA.CORNER_ATTITUDE_STATUS_CD <> 'H'
AND CD.BORROW_USING_TXT <> 'I'
AND CD.BORROW_USING_TXT <> 'J'
AND CA.CORNER_ATTITUDE_STATUS_CD <> 'K'
AND CA.CORNER_ATTITUDE_STATUS_CD <> 'L'
AND CD.BORROW_USING_TXT <> 'M'
AND CD.BORROW_USING_TXT <> 'N'
AND CD.BORROW_USING_TXT <> 'O'
AND CA.CORNER_ATTITUDE_STATUS_CD <> 'P'
AND CD.BORROW_USING_TXT <> 'Q')
AND OC.SERVER_XID IN (400 Integer values);
It's a little hard to read the query without formatting. However, a few things to think about:
Since CA.STAR_0_STRG seems to be boolean, you don't need to use a VARCHAR
Do you really need all of those conditions in your WHERE? Can you reduce or simplify them? I see eleven conditions on the same field, like in CA.CORNER_ATTITUDE_STATUS_CD <> 'K' AND CA.CORNER_ATTITUDE_STATUS_CD <> 'L'.
(Most important) Can you move some of the logic from the condition of your final WHERE to predicates in some of the many JOINs that you're doing? It would help you a lot if you could reduce the amount of data that you're actually joining.

SQL Query - SQL Developer

I have a problem with the below query. Basically the query below gives me all items from a ITEM_MASTER table, that are located at location '9999' from the ITEM_LOCATION table and that have a status of 'C' again in the ITEM_LOCATION table. I want to check if any of these items in the query below are also at any other location and have a status of 'A'.
So basically I want too cross reference the items from this query, to see if any of them also appear at any other location, not just 9999 and if they have a status of 'A'
SELECT IM.ITEM MIN,
IM.ITEM_DESC,
IL.ITEM MIN,
IL.LOC,
IL.STATUS
FROM ITEM_MASTER IM,ITEM_LOC IL
WHERE IM.ITEM_LEVEL = 2
AND IM.TRAN_LEVEL = 2
AND IL.STATUS = 'C'
AND IM.ITEM = IL.ITEM
AND IL.LOC = 9999;
Thanks!
First, you should write your query using proper join syntax:
SELECT IM.ITEM MIN, IM.ITEM_DESC,
IL.ITEM MIN, IL.LOC, IL.STATUS
FROM ITEM_MASTER IM JOIN
ITEM_LOC IL
ON IM.ITEM = IL.ITEM
WHERE IM.ITEM_LEVEL = 2 AND IM.TRAN_LEVEL = 2 AND IL.STATUS = 'C' AND
IL.LOC = 9999;
You can accomplish what you want with exists:
SELECT IM.ITEM MIN, IM.ITEM_DESC,
IL.ITEM MIN, IL.LOC, IL.STATUS
FROM ITEM_MASTER IM JOIN
ITEM_LOC IL
ON IM.ITEM = IL.ITEM
WHERE IM.ITEM_LEVEL = 2 AND IM.TRAN_LEVEL = 2 AND IL.STATUS = 'C' AND
IL.LOC = 9999 AND
EXISTS (SELECT 1
FROM ITEM_MASTER IM2 JOIN
ITEM_LOC IL2
ON IM2.ITEM = IL2.ITEM
WHERE IM2.ITEM = IM.ITEM AND
IL2.LOC <> 9999 AND
IL2.STATUS = 'A'
);