Summing using a case expression - sql

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

Related

Sorry I need to hide

Elon Reeve Musk FRS is an entrepreneur and business magnate. He is the founder, CEO, and Chief Engineer at SpaceX; early-stage investor, CEO, and Product Architect of Tesla, Inc.; founder of The Boring Company; and co-founder of Neuralink and OpenAI.
Your inner select returns a table. That can't be used as parameter to match a WHERE IN condition. Instead try using an INNER JOIN
sum(decode(
select sum(dou.noukn)
from dou
join v_kzeiritsu on
dou.zeiritsu = v_kzeiritsu.zeiritsu
)) as noukn2;
Just move your sum logic inside select as follows:
(SELECT SUM(DOU$2.NOUKN)
FROM SDNISHI.V_KZEIRITSU V
WHERE DOU$2.ZEIRITSU = V.ZEIRITSU) AS NOUKN2
In case If it gives aggregation error then use sum(above query) AS NOUKN2
Your code is very strange. For instance, it seems to assume that V_KZEIRITSU has one row. But, you can move this to the FROM clause:
SELECT SUM(CASE WHEN DOU.ZEIRITSU = K.ZEIRITSU THEN DOU.NOUKN ELSE 0 END) AS NOUKN2
FROM DOU LEFT JOIN
V_KZEIRITSU K
ON 1=1 -- in case the table is really empty
A slightly more reasonable version would be:
SELECT SUM(DOU.NOUKN) AS NOUKN2
FROM DOU LEFT JOIN
V_KZEIRITSU K
ON DOU.ZEIRITSU = K.ZEIRITSU -- in case the table is really empty
It seems rather unlikely to me that this is what you really intend. If not, I would suggest that you ask a new question with appropriate same data, desired results, and explanation of the results. A non-working query should not be expected to provide the same level of information.
I'd say that it is, actually, as simple as
select sum(dou.noukn)
from dou
where dou.zeiritsu in (select zeiritsu from v_kzeiritsu)
(I'm not sure what dou is (table? alias?), but I hope you do.)
After you edited the question, I'm editing the answer. I marked with "--> this" two lines that - in my opinion - might help. As previously, the whole sum(case ...) as noukn2 is replaced by a simple sum(dou$2.noukn).
Note that - in Oracle - you can't use as keyword for table alias. For example:
no: from employees as e
yes: from employees e
Here's your query:
SELECT DOU$2.CUSTCD AS CUSTCD,
DOU$2.CHUNO AS CHUNO,
DOU$2.LINNO AS LINNO,
DOU$2.SHIPDAYYM AS SHIPDAYYM,
SUM (DOU$2.NOUKN) AS NOUKN,
SUM (DOU$2.ZEIKN) AS ZEIKN,
SUM (dou$2.noukn) AS noukn2 --> this
FROM SDNISHI.T_HCHUMON_DOUSOU DOU$2
INNER JOIN SDNISHI.SY_KANRI KNR ON KNR.SHIPDAYYM = DOU$2.SHIPDAYYM
INNER JOIN SDNISHI.T_HCHUMON_MEI MEI
ON MEI.CUSTCD = DOU$2.CUSTCD
AND MEI.CHUNO = DOU$2.CHUNO
AND MEI.LINNO = DOU$2.LINNO
AND MEI.SHIPDAYYM = DOU$2.SHIPDAYYM
AND MEI.USEDNGKBN = '0'
AND MEI.CANCELKBN = '0'
LEFT OUTER JOIN SDNISHI.T_HCHUMON_HD HD
ON HD.CUSTCD = MEI.CUSTCD
AND HD.CHUNO = MEI.CHUNO
AND HD.LINNO = MEI.LINNO
AND HD.USEDNGKBN = '0'
AND HD.CANCELKBN = '0'
AND isnull (HD.CANKBN, '00') = '00'
JOIN v_keziritsu vk ON vk.zeiritsu = dou$2.zeiritsu --> this
WHERE DOU$2.USEDNGKBN = '0'
AND DOU$2.CANCELKBN = '0'
AND ( ( MEI.CHGDELKBN = '1'
AND MEI.HDOUSOUKBN = '02'
AND ( MEI.CHUSU > 0
OR MEI.BCHUSU > 0))
OR ( MEI.CHGDELKBN != '1'
AND HD.HDOUSOUKBN = '02'
AND ( MEI.CHKBTNFGA = '1'
AND HD.CHUSU > 0)
OR ( MEI.CHKBTNFGB = '1'
AND HD.BCHUSU > 0)))
GROUP BY DOU$2.CUSTCD,
DOU$2.CHUNO,
DOU$2.LINNO,
DOU$2.SHIPDAYYM

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.

Query using subqueries in where statement

I have a query with subqueries in the where statement which works fine but I need to improve on it but I am not sure of the best way to go about this.
Basically I am getting last years results for students in this years classes. The code below works fine for classcode '10DRADRA1' but there are many more classes and I want the query to iterate through all classes for 2017 Semester 1. I need to have the classcode included as one of the output fields also. So the query will start with the first class and give all the results for that class, then do the same for the next class in the subquery. I am not sure how to include the classcode in the select statement next to all the results from the previous year.
Note that students may do a number of classes this year so there may be some repetition of the results from the previous year. Every class they do this year should include the students name and their results from the previous year. I hardcoded '10DRADRA1' in just to get things working, if I remove it it provides all students in the school only once, while I want each class they are in once and the same results for every class they are in.
Also not that vStudentReportsSemesterResults is a view that holds all results, StudentClasses is a table which holds the class codes a student is doing and SubjectClasses is a table holding the codes for all classes in the school
Is anyone able to advise on the best way of doing this? Here is my current code.
SELECT vStudentReportsSemesterResults.StudentID,
vStudentReportsSemesterResults.AssessResultsResult,
vStudentReportsSemesterResults.AssessAreaHdgAbbrev2,
vStudentReportsSemesterResults.FileSemester,
vStudentReportsSemesterResults.FileYear,
vStudentReportsSemesterResults.ClassLearningAreaCode,
vStudentReportsSemesterResults.AssessmentCode,
vStudentReportsSemesterResults.StudentNameInternal
FROM vStudentReportsSemesterResults
WHERE vStudentReportsSemesterResults.StudentID in
(
select StudentClasses.ID from StudentClasses
where StudentClasses.filesemester = 1 and
StudentClasses.fileyear = 2017 and
StudentClasses.classcode in
(
select SubjectClasses.ClassCode from SubjectClasses
where SubjectClasses.FileYear = 2017 and
SubjectClasses.FileSemester = 1 and
SubjectClasses.FileType = 'A' and
SubjectClasses.ClassCampus = 'S' and
SubjectClasses.ClassCode like '10DRADRA1'
)
)
and (vStudentReportsSemesterResults.ClassLearningAreaCode = 'ENG' OR
vStudentReportsSemesterResults.ClassLearningAreaCode = 'MAT' OR
vStudentReportsSemesterResults.ClassLearningAreaCode = 'SCI') AND
(vStudentReportsSemesterResults.AssessAreaHdgAbbrev2 = 'Grade' OR
vStudentReportsSemesterResults.AssessAreaHdgAbbrev2 = 'Level') AND
(vStudentReportsSemesterResults.AssessResultsResult <> '') AND
(vStudentReportsSemesterResults.FileYear = 2016) AND
(vStudentReportsSemesterResults.FileSemester = 4)
Join StudentClasses to vStudentReportsSemesterResults:
SELECT
sc.ClassCode,
srsr.StudentID,
srsr.AssessResultsResult,
srsr.AssessAreaHdgAbbrev2,
srsr.FileSemester,
srsr.FileYear,
srsr.ClassLearningAreaCode,
srsr.AssessmentCode,
srsr.StudentNameInternal
FROM vStudentReportsSemesterResults srsr
JOIN StudentClasses sc
ON sc.ID = srsr.StudentID
AND sc.FileSemester = 1
AND sc.FileYear = srsr.FileYear + 1
AND EXISTS
(
select *
from SubjectClasses subc
where subc.FileYear = sc.FileYear
and subc.ClassCode = sc.ClassCode
and subc.FileSemester = sc.FileSemester
and subc.FileType = 'A'
and subc.ClassCampus = 'S'
)
WHERE srsr.ClassLearningAreaCode in ('ENG', 'MAT', 'SCI')
AND srsr.AssessAreaHdgAbbrev2 in ('Grade', 'Level')
AND srsr.AssessResultsResult <> ''
AND srsr.FileYear = 2016
AND srsr.FileSemester = 4;
This is more readable:
SELECT
ClassCode,
StudentID,
AssessResultsResult,
AssessAreaHdgAbbrev2,
ClassLearningAreaCode,
AssessmentCode,
StudentNameInternal,
lr.FileYear,
lr.FileSemester,
tr.FileYear,
tr.FileSemester,
tr.FileType,
tr.ClassCampus
FROM
vStudentReportsSemesterResults lr
inner join (
select ID, sc.ClassCode, sc.FileYear, sc.filesemester, sbjc.FileType, sbjc.ClassCampus
from StudentClasses sc
INNER JOIN SubjectClasses sbjc ON SC.classcode = sbjc.ClassCode and sc.FileSemester=sbjc.FileSemester and sc.FileYear=sbjc.FileYear
) tr on lr.StudentID = tr.ID
and lr.FileYear = tr.FileYear - 1
WHERE
ClassLearningAreaCode IN ('ENG', 'MAT', 'SCI')
AND AssessAreaHdgAbbrev2 IN ('Grade', 'Level')
AND (AssessResultsResult <> '')
AND lr.FileYear = 2016
AND lr.FileSemester = 4
and tr.FileSemester = 1
and tr.FileType = 'A'
and tr.ClassCampus = 'S'
ORDER BY 2,1,5
In SELECT section I have added some fields to better understand result.
In WHERE clause you can control how to filter comparision.
Put some indexes on join and filter columns and the query will run fast

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.

Logic for a specific Count

I want to fill a asp:GridView with a result of a query. My query, has to count the number of ocurrences of a specific status_id IF the column 'san_proposta.credenciada_id' is different of the value 10. If the column 'san_proposta.credenciada_id' is equals of the value 10 in anothers rows, I need count all ocurrences of a specific status_id that has the 'credenciada_id' equal 10.
I'm trying the follow code, but I don't know how to do with this specifics count.
SELECT DISTINCT San_Proposta.Imovel_Id, San_Logradouro.Descricao, San_Endereco.Logradouro, San_Imovel.Numero, San_TipoComplemento.Descricao AS Expr1,
San_Imovel.Complemento, San_Imovel.TipoDsc1, San_Transacao.TransacaoSigla, San_Credenciada.Apelido, San_Transacao.Transacao_ID, COUNT(San_Proposta.StatusProposta_Id) AS NumeroProposta
FROM San_Proposta
JOIN San_Imovel
ON San_Proposta.Imovel_Id = San_Imovel.Imovel_Id
JOIN San_Endereco
ON San_Imovel.Endereco_Id = San_Endereco.Endereco_Id
JOIN San_Logradouro
ON San_Endereco.Logradouro_Id = San_Logradouro.Logradouro_Id
JOIN San_TipoComplemento
ON San_Imovel.TipoComplemento_Id = San_TipoComplemento.TipoComplemento_Id
JOIN San_Transacao
ON San_Imovel.Transacao_ID = San_Transacao.Transacao_ID
JOIN San_Credenciada
ON San_Imovel.Credenciada_Id = San_Credenciada.Credenciada_Id
WHERE (San_Imovel.Credenciada_Id = 10 OR San_Proposta.Credenciada_Id = 10)
GROUP BY San_Proposta.Imovel_Id, San_Logradouro.Descricao, San_Endereco.Logradouro, San_Imovel.Numero,
San_TipoComplemento.Descricao, San_Imovel.Complemento, San_Imovel.TipoDsc1, San_Transacao.TransacaoSigla,
San_Credenciada.Apelido, San_Transacao.Transacao_ID, San_Proposta.StatusProposta_Id,
San_Proposta.Credenciada_Id, San_Imovel.Credenciada_Id
ORDER BY San_Proposta.Imovel_Id DESC
Based on what you're saying (if I'm interpreting you correctly) it looks like
COUNT(CASE WHEN San_Proposta.credenciada_id = 10 THEN San_Proposta.StatusProposta_Id ELSE NULL END)
would work for your count.