Subquery return more than one value - sql

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.

Related

Summing using a case expression

I am looking to roll up my numbers.
SELECT
SORDERQ.SOHNUM_0,
YQTYORD_0,
ORDINVNOT_0
FROM LIVE.SORDER
LEFT JOIN LIVE. SORDERQ ON SORDER.SOHNUM_0 = SORDERQ.SOHNUM_0
WHERE SORDER.SOHNUM_0 = 'SC111-162420_19'
AND ZBPSELECTION_0 <> ''
AND YCROPYR_0 = '2019'
AND SORDER.SALFCY_0 = '111'
I want to return 1 record per SOHNUM_0,the sum of YQTYORD_0 by SOHNUM_0 and ORDINVNOT_0.
I want to return 1 record per SOHNUM_0,the sum of YQTYORD_0 by SOHNUM_0 and ORDINVNOT_0.
Are you just looking for simple aggregation?
SELECT
q.SOHNUM_0,
SUM(YQTYORD_0) SUM_YQTYORD_0,
ORDINVNOT_0
FROM LIVE.SORDER o
LEFT JOIN LIVE.SORDERQ q ON o.SOHNUM_0 = q.SOHNUM_0
WHERE
o.SOHNUM_0 = 'SC111-162420_19'
AND o.SALFCY_0 = '111'
AND ZBPSELECTION_0 <> ''
AND YCROPYR_0 = '2019'
GROUP BY
q.SOHNUM_0,
ORDINVNOT_0
Note:
I modified your query so it uses table aliases - this makes it shorter
you should prefix all columns in the query with the table they belong to, to make your query unmabiguous and easier to understand

Duplicate rows while multiplying two columns of two different tables using joins

I have these following tables
Question_Segment_Master
Question_Set_Details
While I am joining these two tables I am getting duplicate rows..
Please view fiddle,where I posted those twos schema and it's data..
http://sqlfiddle.com/#!18/4c84f/10
This is my expected OP
You need to get the question_marks of each segment. Also, you should JOIN using the branch_id, test_id, subject_code_id along with the segment_id.
Using JOIN and then take Distinct values
SELECT DISTINCT qsm.segment_id, segment_name, segment_description
, must_attend_question AS tot_attented_question, total_question AS tot_questions
, (qsd.question_marks * must_attend_question) AS tot_marks
, '' AS marks_obtain
FROM dbo.Question_Segment_Master AS qsm
INNER JOIN dbo.Question_Set_Details AS qsd
ON (qsd.branch_id = qsm.branch_id AND qsd.test_id = qsm.test_id
AND qsd.segment_id = qsm.segment_id AND qsd.subject_code_id = qsm.subject_code_id)
WHERE qsm.subject_code_id = 1 and qsm.test_id = 1 and qsm.branch_id = 15;
Demo
You were missing the segment_id in your join clause
SELECT DISTINCT
qsm.segment_id,
qsm.segment_name,
qsm.segment_description,
qsm.must_attend_question tot_attented_question,
qsm.total_question tot_questions,
(qsd.question_marks * must_attend_question) tot_marks,
'' AS marks_obtain
FROM dbo.question_segment_master qsm
INNER JOIN dbo.question_set_details qsd on
qsd.test_id = qsm.test_id
and qsd.segment_id = qsm.segment_id
WHERE qsm.test_id=1
AND qsm.branch_id = 15
AND qsm.subject_code_id =1 AND qsd.question_set_id = 1

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.

Confused in join query in SQL

The following works:
SELECT IBAD.TRM_CODE, IBAD.IPABD_CUR_QTY, BM.BOQ_ITEM_NO,
IBAD.BCI_CODE, BCI.BOQ_CODE
FROM IPA_BOQ_ABSTRCT_DTL IBAD,
BOQ_CONFIG_INF BCI,BOQ_MST BM
WHERE BM.BOQ_CODE = BCI.BOQ_CODE
AND BCI.BCI_CODE = IBAD.BCI_CODE
AND BCI.STATUS = 'Y'
AND BM.STATUS = 'Y'
order by boq_item_no;
Results:
But after joining many tables with that query, the result is confusing:
SELECT (SELECT CMN_NAME
FROM CMN_MST
WHERE CMN_CODE= BRI.CMN_RLTY_MTRL) MTRL,
RRI.RRI_RLTY_RATE AS RATE,
I.BOQ_ITEM_NO,
(TRIM(TO_CHAR(IBAD.IPABD_CUR_QTY,
'9999999999999999999999999999990.999'))) AS IPABD_CUR_QTY,
TRIM(TO_CHAR(BRI.BRI_WT_FACTOR,
'9999999999999999999999999999990.999')) AS WT,
TRIM(TO_CHAR((IBAD.IPABD_CUR_QTY*BRI.BRI_WT_FACTOR),
'9999999999999999999999990.999')) AS RLTY_QTY,
(TRIM(TO_CHAR((IBAD.IPABD_CUR_QTY*BRI.BRI_WT_FACTOR*RRI.RRI_RLTY_RATE),
'9999999999999999999999990.99'))) AS TOT_AMT,
I.TRM_CODE AS TRM
FROM
(SELECT * FROM ipa_boq_abstrct_dtl) IBAD
INNER JOIN
(SELECT * FROM BOQ_RLTY_INF) BRI
ON IBAD.BCI_CODE = BRI.BCI_CODE
INNER JOIN
(SELECT * FROM RLTY_RATE_INF) RRI
ON BRI.CMN_RLTY_MTRL = RRI.CMN_RLTY_MTRL
INNER JOIN
( SELECT IBAD.TRM_CODE, IBAD.IPABD_CUR_QTY,
BM.BOQ_ITEM_NO, IBAD.BCI_CODE, BCI.BOQ_CODE
FROM IPA_BOQ_ABSTRCT_DTL IBAD,
BOQ_CONFIG_INF BCI,BOQ_MST BM
WHERE
BM.BOQ_CODE = BCI.BOQ_CODE
AND BCI.BCI_CODE = IBAD.BCI_CODE
and BCI.status = 'Y'
and bm.status = 'Y') I
ON BRI.BCI_CODE = I.BCI_CODE
AND I.TRM_CODE = BRI.TRM_CODE
AND BRI.TRM_CODE =4
group by BRI.CMN_RLTY_MTRL, RRI.RRI_RLTY_RATE, I.BOQ_ITEM_NO,
IBAD.IPABD_CUR_QTY, BRI.BRI_WT_FACTOR, I.TRM_CODE, I.bci_code
order by BRI.CMN_RLTY_MTRL
Results:
TRM should be 11 instead of 4 in the first row.
you getting 4 because you use
AND BRI.TRM_CODE =4
if you remove this criter you can get true result
In your first query, both of the rows you've highlighted have BCI_CODE=1866.
In the second query, you are joining that result set with a number of others (which come from the same tables, which seems odd). In particular, you are joining from the subquery to another table using BCI_CODE, and from there to (SELECT * FROM ipa_boq_abstrct_dtl) IBAD. Since both of the rows from the subquery have the same BCI_CODE, they will join to the same rows in the other tables.
The quantity that you are actually displaying in the second query is from (SELECT * FROM ipa_boq_abstrct_dtl) IBAD, not from the other subquery.
Is the problem simply that you mean to select I.IPABD_CUR_QTY instead of IBAD.IPABD_CUR_QTY?
You might find this clearer if you did not reuse the same aliases for tables at multiple points in the query.

Column is invalid in the ORDER BY clause because it is not contained in either an aggregate function or the GROUP BY clause

Ok here's my View (vw_LiftEquip)
SELECT dbo.tbl_equip_swl_unit.unit_id,
dbo.tbl_equip_swl_unit.unit_name,
dbo.tbl_equip_swl_unit.archived,
dbo.tbl_categories.category_id,
dbo.tbl_categories.categoryName,
dbo.tbl_categories.parentCategory,
dbo.tbl_categories.sub_category,
dbo.tbl_categories.desc_category,
dbo.tbl_categories.description,
dbo.tbl_categories.miscellaneous,
dbo.tbl_categories.category_archived,
dbo.tbl_equip_swl_unit.unit_name AS Expr1,
dbo.tbl_categories.categoryName AS Expr2,
dbo.tbl_categories.description AS Expr3,
dbo.tbl_equip_depts.dept_name,
dbo.tbl_equip_man.man_name,
dbo.tbl_Lifting_Gear.e_defects AS Expr7,
dbo.tbl_Lifting_Gear.e_defects_desc AS Expr8,
dbo.tbl_Lifting_Gear.e_defects_date AS Expr9,
dbo.tbl_equipment.equipment_id,
dbo.tbl_equipment.e_contract_no,
dbo.tbl_equipment.slID,
dbo.tbl_equipment.e_entered_by,
dbo.tbl_equipment.e_serial,
dbo.tbl_equipment.e_model,
dbo.tbl_equipment.e_description,
dbo.tbl_equipment.e_location_id,
dbo.tbl_equipment.e_owner_id,
dbo.tbl_equipment.e_department_id,
dbo.tbl_equipment.e_manafacture_id,
dbo.tbl_equipment.e_manDate1,
dbo.tbl_equipment.e_manDate2,
dbo.tbl_equipment.e_manDate3,
dbo.tbl_equipment.e_dimensions,
dbo.tbl_equipment.e_test_no,
dbo.tbl_equipment.e_firstDate1,
dbo.tbl_equipment.e_firstDate2,
dbo.tbl_equipment.e_firstDate3,
dbo.tbl_equipment.e_prevDate1,
dbo.tbl_equipment.e_prevDate2,
dbo.tbl_equipment.e_prevDate3,
dbo.tbl_equipment.e_insp_frequency,
dbo.tbl_equipment.e_swl,
dbo.tbl_equipment.e_swl_unit_id,
dbo.tbl_equipment.e_swl_notes,
dbo.tbl_equipment.e_cat_id,
dbo.tbl_equipment.e_sub_id,
dbo.tbl_equipment.e_parent_id,
dbo.tbl_equipment.e_last_inspector,
dbo.tbl_equipment.e_last_company,
dbo.tbl_equipment.e_deleted AS Expr11,
dbo.tbl_equipment.e_deleted_desc AS Expr12,
dbo.tbl_equipment.e_deleted_date AS Expr13,
dbo.tbl_equipment.e_deleted_insp AS Expr14,
dbo.tbl_Lifting_Gear.e_defects_action AS Expr15,
dbo.tbl_equipment.e_rig_location,
dbo.tbl_Lifting_Gear.e_add_type AS Expr17,
dbo.tbl_Lifting_Gear.con_id,
dbo.tbl_Lifting_Gear.lifting_date,
dbo.tbl_Lifting_Gear.lifting_ref_no,
dbo.tbl_Lifting_Gear.e_id,
dbo.tbl_Lifting_Gear.inspector_id,
dbo.tbl_Lifting_Gear.lift_testCert,
dbo.tbl_Lifting_Gear.lift_rig_location,
dbo.tbl_Lifting_Gear.inspected,
dbo.tbl_Lifting_Gear.lifting_through,
dbo.tbl_Lifting_Gear.liftingNDT,
dbo.tbl_Lifting_Gear.liftingTest,
dbo.tbl_Lifting_Gear.e_defects,
dbo.tbl_Lifting_Gear.e_defects_desc,
dbo.tbl_Lifting_Gear.e_defects_date,
dbo.tbl_Lifting_Gear.e_defects_action,
dbo.tbl_Lifting_Gear.lift_department_id,
dbo.tbl_Lifting_Gear.lifting_loc
FROM dbo.tbl_equipment
INNER JOIN dbo.tbl_equip_swl_unit
ON dbo.tbl_equipment.e_swl_unit_id = dbo.tbl_equip_swl_unit.unit_id
INNER JOIN dbo.tbl_categories
ON dbo.tbl_equipment.e_cat_id = dbo.tbl_categories.category_id
INNER JOIN dbo.tbl_equip_depts
ON dbo.tbl_equipment.e_department_id = dbo.tbl_equip_depts.dept_id
INNER JOIN dbo.tbl_equip_man
ON dbo.tbl_equipment.e_manafacture_id = dbo.tbl_equip_man.man_id
INNER JOIN dbo.vwSubCategory
ON dbo.tbl_equipment.e_sub_id = dbo.vwSubCategory.category_id
INNER JOIN dbo.vwDescCategory
ON dbo.tbl_equipment.e_cat_id = dbo.vwDescCategory.category_id
INNER JOIN dbo.tbl_Lifting_Gear
ON dbo.tbl_equipment.equipment_id = dbo.tbl_Lifting_Gear.e_id
And here's the select statement with subquery that I am using:
SELECT *
FROM vw_LiftEquip
WHERE lifting_loc = ? AND
con_id = ? AND
EXPR11 =
'N'(
SELECT MAX(lifting_date) AS maxLift
FROM vw_LiftEquip
WHERE e_id = equipment_id
)
ORDER BY lifting_ref_no,
category_id,
e_swl,
e_serial
I get the error :
Column "vw_LiftEquip.category_id" is invalid in the ORDER BY clause because it is not contained in either an aggregate function or the GROUP BY clause.
Can't see why its returning that error, this is admittedly the first time I've ran a subquery on such a complex view, and I am a bit lost, thanks in advance for any help. I have looked through the similar posts and can find no answers to this one, sorry if I am just being dumb.
You are missing AND between EXPR11 = 'N' and (SELECT MAX(...
Otherwise, it looks OK. MAX without GROUP BY is allowed if you have no other columns in the SELECT
Update: #hvd also noted that you have nothing to compare to MAX(lifting_date). See comment
Update 2,
SELECT *
FROM vw_LiftEquip v1
CROSS JOIN
(
SELECT MAX(lifting_date) AS maxLift
FROM vw_LiftEquip
WHERE e_id = equipment_id
) v2
WHERE v1.lifting_loc = ? AND
v1.con_id = ? AND
v1.EXPR11 = 'N'
ORDER BY v1.lifting_ref_no,
v1.category_id,
v1.e_swl,
v1.e_serial