Here is my current query:
SELECT sac.cred, s.status, (SELECT NVL (csl.census_dates, tl.census_dates)
FROM schema.sections cs, schema.sections_ls csl, schema.terms tl
WHERE cs.course_sections_id = csl.course_sections_id(+)AND csl.pos(+) = 1 AND cs.term = tl.terms_id
AND tl.pos = 1 AND cs.course_sections_id = cs2.course_sections_id AND ROWNUM = 1)AS censusDate,
(SELECT NVL (p.ssn, 'xxx-xx-xxxx') FROM schema.person p
WHERE p.id = sac.person_id) AS ssn,
//schema.person_name(sac.person_id, 'FML') as fml,
//schema.person_name(sac.person_id, 'LF') as lf
FROM schema.student_acad_cred sac JOIN schema.statuses s
ON s.student_acad_cred_id = sac.student_acad_cred_id
JOIN schema.terms tl ON sac.term = tl.terms_id
JOIN schema.student_course_sec scs ON sac.student_course_sec = scs.student_course_sec_id
JOIN schema.course_sections cs2 ON scs.course_section = cs2.course_sections_id
JOIN schema.terms t ON tl.terms_id = t.terms_id
WHERE sac.person_id = '1111111111'
AND (s.status IN ('A', 'N') OR (s.status = 'D' AND final_grade IS NOT NULL))
AND s.pos = '1'AND tl.pos = '1' AND tl.terms_id = 'spring';
And here are the results:
cred status currentDate censusDate ssn
==== ====== =========== ========== ===
3 N 11/16/2011 12/15/2011 xxx-xx-xxxx
4 N 11/16/2011 12/15/2011 xxx-xx-xxxx
3 N 11/16/2011 12/15/2011 xxx-xx-xxxx
4 N 11/16/2011 12/15/2011 xxx-xx-xxxx
1 N 11/16/2011 12/15/2011 xxx-xx-xxxx
Okay, what I am trying to do is use sum() (or some other function) to add up all the credit hours that are pulled. So in this instance the sum of all cred hours would be '15'. Is there a way to do this in query? Ideally I would want something like this:
cred status currentDate censusDate ssn
==== ====== =========== ========== ===
15 N 11/16/2011 12/15/2011 xxx-xx-xxxx
The way to do this is to GROUP BY all of your other columns. Since you can't group by aliased columns directly (in Oracle and most RDMBSes), you have to wrap the whole thing in another query and do the grouping there.
SELECT SUM(cred), status, censusDate, ssn
FROM
(SELECT sac.cred, s.status,
(SELECT NVL (csl.census_dates, tl.census_dates)
FROM schema.sections cs, schema.sections_ls csl, schema.terms tl
WHERE cs.course_sections_id = csl.course_sections_id(+)AND csl.pos(+) = 1 AND cs.term = tl.terms_id
AND tl.pos = 1 AND cs.course_sections_id = cs2.course_sections_id AND ROWNUM = 1)AS censusDate,
(SELECT NVL (p.ssn, 'xxx-xx-xxxx') FROM schema.person p
WHERE p.id = sac.person_id) AS ssn,
//schema.person_name(sac.person_id, 'FML') as fml,
//schema.person_name(sac.person_id, 'LF') as lf
FROM schema.student_acad_cred sac JOIN schema.statuses s
ON s.student_acad_cred_id = sac.student_acad_cred_id
JOIN schema.terms tl ON sac.term = tl.terms_id
JOIN schema.student_course_sec scs ON sac.student_course_sec = scs.student_course_sec_id
JOIN schema.course_sections cs2 ON scs.course_section = cs2.course_sections_id
JOIN schema.terms t ON tl.terms_id = t.terms_id
WHERE sac.person_id = '1111111111'
AND (s.status IN ('A', 'N') OR (s.status = 'D' AND final_grade IS NOT NULL))
AND s.pos = '1'AND tl.pos = '1' AND tl.terms_id = 'spring')
GROUP BY status, censusDate, ssn;
This looks ugly, but doesn't actually have a horrible performance impact.
select groupcol, sum(cred)
from table1
group by rollup(groupcol)
Related
I have this SQL code here, my wish is to calculate the latest fee balance per student for each deposit made. So far I have been able to achieve this but now the question is how I'm I to select only the latest balance while disregarding the other previous entries/Balances
(select
f.Totals -SUM(Total) OVER(ORDER BY pay_Id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as Balance,
p.Total as 'TotalPaid',
c.class_id as 'ClassID',
p.std_ID as 'STDID',
c.class_name as 'Class',
a.ad_stdname as 'Name',
t.term_id as 'TermID',
t.term_name as 'Term',
p.Date as 'Date',
case when (st.str_id = null) then '-' else st.str_id end as 'StrID',
case when (p.Tution_fee = null) then '0' else p.Tution_fee end as 'Tution',
case when (p.adm_fee = null) then '0' else p.adm_fee end as 'Admission',
case when (p.Activity_fee = null) then '0' else p.Activity_fee end as 'Activity',
case when (p.Textbk_Statio = null) then '0' else p.Textbk_Statio end as 'Texbooks',
case when (p.Transport_fee = null) then '0' else p.Transport_fee end as 'Transport'
from Payments p
inner join Admissions a
on a.ad_id = p.std_ID
inner join classes c
on c.class_id =p.class_id
inner join fees f on f.fee_classID = p.class_id and f.Term_id = p.Term_id
left join streams st
on st.str_id = p.str_id
inner join terms t
on p.Term_id = t.term_id
where a.ad_id = 29
)
order by p.std_name,Balance,p.Date desc
This is my current output
I have selected min value for each user in below example:
user date value
Sonu 1/2/2010 1.5
Monu 1/3/2010 2.5
Arun 8/4/2009 3.5
Sonu 2/2/2010 1.0
Monu 12/2/2009 0.5
select t.username, t.date, t.value
from MyTable t
inner join (
select username, min(value) as value
from MyTable
group by username
) tm on t.username = tm.username and t.value = tm.value
Demo sql Fiddle
Use above logic to implement in your code
I tried to accommodate above logic in you query. for now i have just used stdid for grouping, you may add more accordingly. you might get some syntax error:
with MyTable as (select
f.Totals -SUM(Total) OVER(ORDER BY pay_Id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as Balance,
p.Total as 'TotalPaid',
c.class_id as 'ClassID',
p.std_ID as 'STDID',
c.class_name as 'Class',
a.ad_stdname as 'Name',
t.term_id as 'TermID',
t.term_name as 'Term',
p.Date as 'Date',
case when (st.str_id = null) then '-' else st.str_id end as 'StrID',
case when (p.Tution_fee = null) then '0' else p.Tution_fee end as 'Tution',
case when (p.adm_fee = null) then '0' else p.adm_fee end as 'Admission',
case when (p.Activity_fee = null) then '0' else p.Activity_fee end as 'Activity',
case when (p.Textbk_Statio = null) then '0' else p.Textbk_Statio end as 'Texbooks',
case when (p.Transport_fee = null) then '0' else p.Transport_fee end as 'Transport'
from Payments p
inner join Admissions a
on a.ad_id = p.std_ID
inner join classes c
on c.class_id =p.class_id
inner join fees f on f.fee_classID = p.class_id and f.Term_id = p.Term_id
left join streams st
on st.str_id = p.str_id
inner join terms t
on p.Term_id = t.term_id
where a.ad_id = 29
order by p.std_name,Balance,p.Date desc) select * from MyTable
inner join
(
select STDID, min(Balance) as value
from MyTable
group by STDID
) tm on t.STDID = tm.STDID and t.Balance = tm.Balance
I pulled person_nbrs that have never had an EventType1 before or after an EventType2. I need to pull person_nbrs that have not had an EventType1 prior to having an EventType2. If they had an EventType1 after an EventType2, than it is to be ignored. Here is my query that pulls person_nbrs that have never had an EventType1 before or after EventType2.
SELECT
person_nbr, enc_nbr, enc_timestamp
FROM
person p
JOIN
patient_encounter pe ON p.person_id = pe.person_id
JOIN
patient_procedure pp ON pe.enc_id = pp.enc_id
WHERE
enc_timestamp >= '20170101'
--EventType2
AND code_id LIKE '2'
-- EventType1
AND person_nbr NOT IN (SELECT person_nbr
FROM person p
JOIN patient_encounter pe ON p.person_id = pe.person_id
JOIN patient_procedure pp ON pe.enc_id = pp.enc_id
WHERE code_id LIKE '1')
GROUP BY
person_nbr, enc_nbr, enc_timestamp
ORDER BY
person_nbr ;
You can do this with aggregation and a HAVING clause:
SELECT p.person_nbr
FROM person p JOIN
patient_encounter pe
ON p.person_id = pe.person_id JOIN
patient_procedure pp
ON pe.enc_id = pp.enc_id
GROUP BY p.person_nbr
HAVING SUM(CASE WHEN pp.code_id = 2 THEN 1 ELSE 0 END) > 0 AND -- has code 2
(MAX(CASE WHEN pp.code_id = 1 THEN pe.timestamp END) IS NULL OR
MAX(CASE WHEN pp.code_id = 1 THEN pe.timestamp END) < MIN(CASE WHEN pp.code_id = 2 THEN pe.timestamp END)
) ;
The HAVING clause has two parts:
The first specifies that the person has a code = 2.
The second specifies one of two conditions. The first is that there is no code = 1. The second alternative is that the latest c = 1 timestamp is less than the earliest code = 2 timestamp.
Since yesterday I am stuck with this request, it returns an error when hs.HOSPITALIZESPECIALTYID equal to 3 or 4. But when my field equals 1 or 2 it works.
hs.HOSPITALIZESPECIALTYID = 1 ====> su.UNITKEY equals 3 or 4
hs.HOSPITALIZESPECIALTYID = 2 ====> su.UNITKEY equals 9 or 10
hs.HOSPITALIZESPECIALTYID = 3 ====> su.UNITKEY equals 12
hs.HOSPITALIZESPECIALTYID = 4 ====> su.UNITKEY equals 13 or 14
And here is the error:
The subquery returned more than 1 values. This is not allowed when the subquery follows =,! =, <, <=,>,> = Or when it is used as an expression.
Thanks for your help
select c.[HISTORYNUMBER]
,c.[NAMECUSTOMER]
,c.[FIRSTSURNAMECUSTOMER]
--,c.[SECONDSURNAMECUSTOMER]
,ts.DESCRIPTION as Genre
,convert(date,c.[DATEBIRTH],103) as 'Date de naissance'
,c.[ADDRESS]
,a.[ENTITY]
,s.SPECIALTYDESCRIPTION
,su.DESCRIPTION as Unité
,hs.HOSPITALIZATIONDATE
,hs.OUTPUTDATE
,hs.MOVEMSPECIALITYID
from HealthcareProcs..HospProcess hs
inner join PatientManagement..Customer c
on c.CUSTOMERID = hs.CUSTOMERID
inner join Configuration..agreement a
on hs.AGREEMENTID = a.[KEY]
inner join Configuration..specialty s
on s.[KEY] = hs.HOSPITALIZESPECIALTYID
left join configuration..SpecialtyUnits su
on su.SPECIALTY = s.[KEY]
inner join Configuration..Hospitalspecialty hsp
on hsp.SPECIALITYID = s.[KEY]
inner join configuration..tables ts
on ts.[KEY] = c.GENDER
and ts.[TABLE] = 'EstGenero'
where hs.outputdate is null
and hs.HOSPITALIZESPECIALTYID in (3)
and hs.ENTRYID is not null
--and hospitalizationdate >= #datedebut + ' 00:00:00'
--and hospitalizationdate <= #datefin+ ' 23:59:59'
--and hsp.HEALTHCENTREID = #centre
and su.UNITKEY in (12)
and c.GENDER in (case
when (su.UNITKEY = 4 or su.UNITKEY = 10) and (hs.HOSPITALIZESPECIALTYID = 1 or hs.HOSPITALIZESPECIALTYID = 2) then 0
when (su.UNITKEY = 3 or su.UNITKEY = 9) and (hs.HOSPITALIZESPECIALTYID = 1 or hs.HOSPITALIZESPECIALTYID = 2) then 1
when (su.UNITKEY in (3,4) or su.UNITKEY in (9,10) ) and (hs.HOSPITALIZESPECIALTYID = 1 or hs.HOSPITALIZESPECIALTYID = 2) then (select distinct gender from PatientManagement..Customer where GENDER in (0,1))
when hs.HOSPITALIZESPECIALTYID = 3 then (select [key] from configuration..tables ts where ts.[TABLE] = 'EstGenero')
when hs.HOSPITALIZESPECIALTYID = 4 and su.UNITKEY in (13,14) then (select [key] from configuration..tables ts where ts.[TABLE] = 'EstGenero')
end)
Do either of these queries return more than one value?
select distinct gender from PatientManagement..Customer where GENDER in (0,1)
select [key] from configuration..tables ts where ts.[TABLE] = 'EstGenero'
Since when your fields are 1 or 2 it works, I think the second query is the one returning more than one value.
OK, I need somehelp. I have the following two queries:
SELECT DA.OWNG_OCD AS OFFICE, 'FL' AS STATE, SUM(S.STK_END_SEQ_NUM -
S.STK_STRT_SEQ_NUM) + COUNT(*) AS TOTSTK FROM STKRNG S, DFACCT DA, CMPNT C
WHERE RANGE_USED_SW = 'N' AND S.DFTACCT_CANUM = DA.DFTACCT_CANUM
AND DA.OWNG_OCD = C.OCD AND C.ST = 'FL' AND S.STK_TYP = 'R' GROUP
BY DA.OWNG_OCD;
AND
SELECT C.OCD, COUNT(*) AS USED FROM DRAFT D
JOIN STKRNG S ON S.DFTACCT_CANUM = D.DFTACCT_CANUM
JOIN DFACCT DA ON S.DFTACCT_CANUM = DA.DFTACCT_CANUM
JOIN CMPNT C ON CMPNT.OCD = DA.OWNG_OCD
WHERE D.DRFT_SEQ_NUM >= (SELECT MIN(S.STK_STRT_SEQ_NUM) FROM STKRNG S
WHERE D.DFTACCT_CANUM = S.DFTACCT_CANUM AND S.RANGE_USED_SW = 'N')
AND D.DRFT_SEQ_NUM <= (SELECT MAX(S.STK_END_SEQ_NUM) FROM STKRNG S WHERE
D.DFTACCT_CANUM = S.DFTACCT_CANUM AND S.RANGE_USED_SW = 'N')
AND S.STK_TYP = 'R'
AND S.RANGE_USED_SW = 'N'
AND C.ST = 'FL'
GROUP BY C.OCD;
I am trying to write one query where the results of the COUNT in the second query are subtracted from the results of the COUNT in the first query. Any idea on how to do this?
Put your queries in the from clause of your final query:
select q1.totstk - q2.used
from ( <your first query here> ) q1
join ( <your second query here> ) q2 on q2.ocd = q1.office;
try Something like this:
with STKRNGMINMAX as (
SELECT S.DFTACCT_CANUM,
MIN(S.STK_STRT_SEQ_NUM) MINNUM, MAX(S.STK_END_SEQ_NUM) MAXNUM,
SUM(S.STK_END_SEQ_NUM - S.STK_STRT_SEQ_NUM) DIFFNUM
FROM STKRNG S
WHERE (S.RANGE_USED_SW, S.STK_TYP)=('N', 'R')
group by S.DFTACCT_CANUM
)
SELECT C.OCD, S.DIFFNUM - COUNT(*) AS TOTSTK,
FROM DRAFT D
INNER JOIN STKRNGMINMAX S ON S.DFTACCT_CANUM = D.DFTACCT_CANUM and D.DRFT_SEQ_NUM between S.MINNUM AND S.MAXNUM
INNER JOIN DFACCT DA ON S.DFTACCT_CANUM = DA.DFTACCT_CANUM
INNER JOIN CMPNT C ON C.OCD = DA.OWNG_OCD and C.ST='FL'
GROUP BY C.OCD;
Please help me with below problem.
table 1 employee details
emp name empno.
---------------------------------
John 1234
Joe 6789
table 2 employee assignment
empno assignmentstartdate assignmentenddate assignmentID empassignmentID
-----------------------------------------------------------------------------
1234 01JAN2017 02JAN2017 A1 X1
6789 01jan2017 02JAN2017 B1 Z1
table 3 employee assignment property
empassignmentID assignmentID propertyname propertyvalue
-------------------------------------------------------------------
X1 A1 COMPLETED true
X1 A1 STARTED true
Z1 B1 STARTED true
Z1 B1 COMPLETED false
Result wanted: (count of completed and started for each employee)
emp name emp no. COMPLETED STARTED
------------------------------------------
John 1234 1 1
Joe 6789 0 1
Currently with my query it is not putting count correctly for propertyvalue if I run for one employee it works correctly but not for multiple employees.
Please help.
SELECT empno ,
empname ,
(SELECT COUNT(A.propertyvalue)
FROM employeedetails C ,
employees_ASSIGNMENT RCA,
employee_assignment_property A
WHERE TRUNC(startdate) >= '14jun2017'
AND TRUNC(endate) <= '20jun2017'
AND RCA.empno = C.empno
AND RCA.empassignmetid = A.empassignmetid
AND rca.EMPNO IN ('1234','6789')
AND RCA.assignmentid = A.assignmentid
AND A.Name = 'COMPLETED'
AND A.propertyvalue = 'true') ,
(SELECT COUNT(A.propertyvalue)
FROM employeedetails C ,
employees_ASSIGNMENT RCA,
employee_assignment_property A
WHERE TRUNC(startdate) >= '14jun2017'
AND TRUNC(endate) <= '20jun2017'
AND RCA.empno = C.empno
AND RCA.empassignmetid = A.empassignmetid
AND rca.EMPNO IN ('1234','6789')
AND RCA.assignmentid = A.assignmentid
AND A.Name = 'STARTED'
AND A.propertyvalue = 'true')FROM employeedetails WHERE EMPNO IN
('1234','6789') GROUP BY C.empno ,
C.EMPNAME
I think you are simply looking for this:
SELECT DET.empname
, COUNT(CASE WHEN PROP.propertyname = 'COMPLETED' THEN 1 END) COMP_COUNT
, COUNT(CASE WHEN PROP.propertyname = 'STARTED' THEN 1 END) START_COUNT
FROM employeedetails DET
INNER JOIN employees_ASSIGNMENT ASS
ON ASS.empno = DET.empno
INNER JOIN employee_assignment_property PROP
ON PROP.empassignmentID = ASS.empassignmentID
AND PROP.assignmentID = ASS.assignmentID
GROUP BY DET.empname
Just add a WHERE clause if you need one.
if you want you result as a query without CTEs this should work:
select empName,
empNo,
(select employee_details.empNo, count(employee_assignment.assId)
from employee_details as t1
join employee_assignment on (t1.empno = employee_assignment.empno)
join employee_assignment_property on (employee_assignment.assId = employee_assignment_property.assId)
where employee_assignment.ptop = 'COMPLETED'
and t.empNo = t1.empNo
group by t1.empNo ) as [COMPLETED],
(select employee_details.empNo, count(employee_assignment.assId)
from employee_details as t1
join employee_assignment on (t1.empno = employee_assignment.empno)
join employee_assignment_property on (employee_assignment.assId = employee_assignment_property.assId)
where employee_assignment.ptop = 'STARTED'
and t.empNo = t1.empNo
group by t1.empNo ) as [STARTED],
from employee_details as t
If you don't want to do a dirty query composed of subqueries, you can try creating a view (if your database permits it).
What does it mean : I'll be useless in front of this. In summary, a view is a temporary table.
Hope this helps
this should work using CTEs:
Using Common Table Expressions
with numComplet()
as
(
select tbl1.empNo, count(tbl2.assId)
from tbl1
join tbl2 on (tbl1.empno = tbl2.empno)
join tbl3 on (tbl2.assId = tbl3.assId)
where tbl2.ptop = 'COMPLETED'
group by tbl1.empNo
),
with numStarted()
as
(
select tbl1.empNo, count(tbl2.assId)
from tbl1
join tbl2 on (tbl1.empno = tbl2.empno)
join tbl3 on (tbl2.assId = tbl3.assId)
where tbl2.ptop = 'STARTED'
group by tbl1.empNo
)
select *
from tbl1
join numComplet on (tbl1.empNo = numComplet.empNo)
join numStarted on (tbl1.empNo = numStarted.empNo)
I put down table names as tbl[1|2|3]