Sorry I need to hide - sql

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

Related

Case When + IN combination

I'm a bit stuck in my coding here... I have this extense and complex code, but I'm actually failling by the end of it. I'm getting the SQL Error [42804]: ERROR: argument of CASE/WHEN must be type boolean, not type character varying
The thing, is: when "bairro" matches a row from "SUB_COUNTRY_DB", get psd.name, else get z.name. Any tips on how I could accomplish this?
select distinct
aa.mes,
--aa.modalidade,
--to_date(aa.created_date, 'yyyy-mm-dd') data_captacao,
ucl.ja_comprou_lf as comprou_lf,
case when bairro in (select sub_country from sub_country_DB)
then psd.name
else z.name
end loja,
count (distinct aa.customer_uid) qtde_socios,
count (distinct aa.assinatura_uid) qtde_assinaturas
from assinaturas_ativas aa
left join ultima_compra_loja_fisica ucl on (aa.customer_uid = ucl.customer_uid
and aa.mes = ucl.mes)
left join zip_code z on (aa.customer_uid = z.customer_uid
and aa.mes = z.mes)
left join SUB_COUNTRY_DB psd
on (psd.district = aa.bairro)
group by 1,2,3--,4
Try variants like:
moving condition to an inner query
CASE WHEN EXISTS (SELECT DISTINCT sub_country FROM sub_country_DB WHERE sub_country = barrio)
ANY (PostgreSQL only)
CASE WHEN bairro = ANY(ARRAY_AGG(select sub_country from sub_country_DB))

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

IF THEN in SQL Select Statement

I'm writing a report to return vendor names from journal transactions. Here are the basics of the query below.
I am using data from two views:
Journal detail view = pa_journal_detail
Vendor detail view = ap_vendor
Match on Vendor Number:
The vendor number is contained in the following fields:
ap_vendor.a_vendor_number
pa_journal_detail.jl_ref1 [under certain criteria shown below] ONLY WHEN the journal source code is "API" or "APM"
The source code is stored in the field pa_journal_detail. jl_source_code
The vendor name is stored in the field ap_vendor.a_vendor_name
This is the query I had started with. It is returning incorrect syntax errors when I attempt to run.
SELECT
CASE
WHEN pa_journal_detail. jl_source_code = ‘API’
OR pa_journal_detail. jl_source_code = ‘APM’
THEN(
SELECT a_vendor_name
FROM ap_vendor
INNER JOIN pa_journal_detail
ON pa_journal_detail.jl_ref1 = ap_vendor.a_vendor_number)
ELSE 0
END as a_vendor_name, *
FROM pa_journal_detail
Here is the full query below. I have also tried it with the "TOP 1" included as well. I am now getting the error that there is incorrect syntax near the keyword AS.
SELECT
pa_journal_detail.a_project
,pa_journal_detail.jl_seg2
,pa_journal_detail.jl_seg3
,pa_journal_detail.jl_seg4
,pa_journal_detail.jl_source_code
,pa_journal_detail.jl_ref1
,pa_journal_detail.jl_gl_org
,pa_journal_detail.jl_gl_obj
,pa_journal_detail.jl_line_num
,pa_journal_detail.jl_journal_num
,pa_journal_detail.jl_jnl_year_period
,pa_journal_detail.jl_journal_number
,pa_journal_detail.jl_journal_seq
,(SELECT(CASE
WHEN pa_journal_detail. jl_source_code = 'API'
OR pa_journal_detail. jl_source_code = 'APM'
THEN(
SELECT TOP 1 a_vendor_name
FROM ap_vendor
RIGHT JOIN pa_journal_detail
ON pa_journal_detail.jl_ref1 = ap_vendor.a_vendor_number
)
ELSE 0
END as 'a_vendor_name', *
FROM pa_journal_detail))
FROM pa_journal_detail
This is what I ended up with and its working now! Thank you all!
SELECT
pa_journal_detail.a_project
,pa_journal_detail.jl_seg2
,pa_journal_detail.jl_seg3
,pa_journal_detail.jl_seg4
,pa_journal_detail.jl_source_code
,pa_journal_detail.jl_ref1
,pa_journal_detail.jl_gl_org
,pa_journal_detail.jl_gl_obj
,pa_journal_detail.jl_line_num
,pa_journal_detail.jl_journal_num
,pa_journal_detail.jl_jnl_year_period
,pa_journal_detail.jl_journal_number
,pa_journal_detail.jl_journal_seq
,iif((pa_journal_detail.jl_source_code = 'API'
OR pa_journal_detail.jl_source_code = 'APM')
,(SELECT TOP 1 a_vendor_name
FROM ap_vendor
RIGHT JOIN pa_journal_detail
ON pa_journal_detail.jl_ref1 = ap_vendor.a_vendor_number)
,0) as 'a_vendor_name'
FROM pa_journal_detail
for string compare you need to use single quote
CASE
WHEN pa_journal_detail. jl_source_code = 'API'
OR pa_journal_detail. jl_source_code = 'APM'
THEN(
SELECT top 1 a_vendor_name -- here you need limit or top 1
FROM ap_vendor
INNER JOIN pa_journal_detail
ON pa_journal_detail.jl_ref1 = ap_vendor.a_vendor_number
)
ELSE 0
END as a_vendor_name, *
FROM pa_journal_detail
There is also iif(). I use it far more often than I should, I just like have a tiny little if for simple conditional work instead of big ole' Case statement.
select iif(1 = 1,'True','False')
-- any series that results in a boolean
select iif((1 = 1 and 0 = 0) and (5 / 1 = 5 and 5 % 10 = 5),'True','False')
for your query
SELECT
pa_journal_detail.a_project
,pa_journal_detail.jl_seg2
,pa_journal_detail.jl_seg3
,pa_journal_detail.jl_seg4
,pa_journal_detail.jl_source_code
,pa_journal_detail.jl_ref1
,pa_journal_detail.jl_gl_org
,pa_journal_detail.jl_gl_obj
,pa_journal_detail.jl_line_num
,pa_journal_detail.jl_journal_num
,pa_journal_detail.jl_jnl_year_period
,pa_journal_detail.jl_journal_number
,pa_journal_detail.jl_journal_seq
,iif(pa_journal_detail.jl_source_code = 'API' OR pa_journal_detail.jl_source_code = 'APM',(SELECT TOP 1 a_vendor_name
FROM ap_vendor
RIGHT JOIN pa_journal_detail
ON pa_journal_detail.jl_ref1 = ap_vendor.a_vendor_number)
,0)
'a_vendor_name', *
FROM pa_journal_detail))
FROM pa_journal_detail
I think a case expression may be the wrong tool for the job. If you want to join a table sometimes, a left join may be easier:
SELECT p.*, a.a_vendor_name
FROM pa_journal_detail p
LEFT JOIN ap_vendor a ON p.jl_ref1 = a.a_vendor_number AND
p.jl_source_code IN ('API', 'APM')

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

Query from multiple tables with multiple where conditions in the tables

I'm trying to get a count of all speakers who are active regarding that item as well as the total of speakers who correlate to a certain item. The first LEFT JOIN for the total speakers works, but the other for ONLY the active speakers regarding that item doesn't, any help is appreciated. The SQLFiddle is here
http://sqlfiddle.com/#!3/b579d/1
But when I try to add in the portion where you would get the number of active speakers
(LEFT JOIN (SELECT COUNT (tbl_SpeakerCard_Log.SpeakerName)
WHERE tbl_Speaker_Log.Spoken = 0)
ON tbl_AgendaList.AID = tbl_SpeakerCard_Log.AID)
under the previous LEFT JOIN I get an error. I'm 100% sure the query is wrong in some form, but I'm not sure how to approach it.
*NOTE: Spoken/Active are interchangeable, I just use different wording to clarify what I'm looking for.
EDIT: This is the desired output
http://imgur.com/yP1FKxg
You can use conditional aggregation to do this:
SELECT
AgendaList.AID,
AgendaList.Item,
COUNT(SpeakerList.SPID) as SpeakerTotal,
SUM(CASE WHEN SpeakerList.Spoken = 0 THEN 1 ELSE 0 END) as ActiveSpeakers
FROM AgendaList
LEFT JOIN SpeakerLIST ON AgendaList.AID = SpeakerList.AID
GROUP BY AgendaList.AID, AgendaList.Item;
Sample SQL Fiddle
Or you could use count instead of sum (which might be clearer):
COUNT(CASE WHEN Spoken = 0 THEN Spoken END) as ActiveSpeakers
SQL FIDDLE
WITH sTotal AS (
SELECT AgendaList.AID, AgendaList.Item, COUNT( SpeakerList.SPID) as SpeakerTotal
FROM AgendaList
LEFT JOIN SpeakerLIST ON AgendaList.AID = SpeakerList.AID
GROUP BY AgendaList.AID, AgendaList.Item
),
sActive AS (
SELECT AgendaList.AID, AgendaList.Item, COUNT( SpeakerList.SPID) as SpeakerActive
FROM AgendaList
LEFT JOIN SpeakerLIST ON AgendaList.AID = SpeakerList.AID
WHERE SpeakerLIST.Spoken = 0
GROUP BY AgendaList.AID, AgendaList.Item
)
SELECT sTotal.*, sActive.SpeakerActive
FROM sTotal left join
sActive on sTotal.AID = sActive.AID