Multiple conditions in select statement based on values - sql

I have a multiple ctes. In my select statement I must filter values base on the conditions. This is my query.
SELECT roadName
,sum(roadLength) AS sumRoadLength
,avg(elevationDifference) AS eglAvgDepth
,avg(elevationDifference) AS pglAvgDepth
,
FROM cte3
GROUP BY roadName
ORDER BY roadName
Under "elevationDifference" there are lots of values ranging from -10 to +20 which are spread through "roadName". What i want to accomplished is that "eglAvgDepth" will return if all "elevationDifference" values are <0 and take the average. Same case with pglAvgDepth where values are >0.
I tried to add where statement but works only in eglAvgDepth
WHERE elevationDifference < 0
GROUP BY roadName
ORDER BY roadName

Just add a conditional expression:
avg(case when elevationDifference < 0 then elevationDifference end) as eglAvgDepth,
avg(case when elevationDifference > 0 then elevationDifference end) as pglAvgDepth,
EDIT:
You have phrased this that you want the value based on whether all the values are positive or negative. If so:
(case when max(elevationDifference) < 0 then avg(elevationDifference) end) as eglAvgDepth,
(case when max(elevationDifference) > 0 then avg(elevationDifference) end) as pglAvgDepth,

Related

SQL using SUM in CASE in SUM

I had this query select
sum(CASE WHEN kpi.average >= temp.average THEN 1 ELSE 0 END) AS recordOrder,
which worked fine, but I had to change it to this
sum(CASE WHEN sum(kpi.averageUse) / sum(kpi.averageTotal) >= temp.average THEN 1 ELSE 0 END) AS recordOrder,
These queries have to get number of rows, where some value (average) is greater than average from TEMP table. But in the second query I have more accurate data (weighted average).
but I am getting error
1111 invalid use of group function
Any ideas how to write SUM in CASE in SUM?
Thanks!
This code is just non-sensical because you have nested sum functions:
sum(CASE WHEN sum(kpi.averageUse) / sum(kpi.averageTotal) >= temp.average THEN 1 ELSE 0 END) AS recordOrder,
Without seeing your larger query, it is not possible to know what you really intend. But I would speculate that you don't want the internal sum()s:
sum(CASE WHEN (skpi.averageUse / kpi.averageTotal) >= temp.average THEN 1 ELSE 0 END) AS recordOrder,

ORACLE - How to count the total of two queries(with different WHERE clauses) from same table?

I want to capture the aggregate of each number but am not sure how to gather all the results from a couple of queries(All data from the same table) that have different 'WHERE' criteria.
For example,
1st query:
SELECT * FROM tbl
WHERE tbl.from IN ('NIVA', 'TIRB', 'RIFG', 'PWDF')
AND tbl.send_date > TRUNC(SYSDATE) - 30
GROUP BY tbl.job_nbr;
2nd query:
SELECT * FROM tbl
WHERE tbl.from IN ('GGGB','GVCE','GMWA','GTYR')
AND tbl.to IN ('GGGBP2','GVCEP3','GMWAP1','GTYRP3')
AND tbl.send_date > TRUNC(SYSDATE) - 30
GROUP BY tbl.job_nbr;
I'm not sure if just using a WHERE clause satisfy my requirement
WHERE tbl.from IN ('NIVA', 'TIRB', 'RIFG', 'PWDF')
AND tbl.from IN ('GGGB','GVCE','GMWA','GTYR')
AND tbl.to IN ('GGGBP2','GVCEP3','GMWAP1','GTYRP3')
Where I get confused is that results that are produced by my 1st query don't need to meet the 1st AND operator condition of the 2nd query. It seems if I incorporate all of my listed values in the 'tbl.from IN' condition and use the AND operator('tbl.to IN') that the returned results will only be those listed in the 'tbl.from IN' condition with the 'tbl.to IN' column.
Both queries produce separate results obviously, but I want to combine set of results so that I can count all occurrences, GROUP'ed BY unique job number(tbl.job_nbr).
*Note: I'm a little concerned about performance as well, because I want to incorporated in a larger query.
I'm sure its something simple, or at least somewhat simple, but I've spent a lot of time trying to figure this out. If anyone would be kind enough help me out, I would greatly appreciate it!
If I did not explain clearly enough or anyone has additional questions, I'll do my best to clarify.
I think you want conditional aggregation:
SELECT tbl.job_nbr,
SUM(CASE WHEN tbl.from IN ('NIVA', 'TIRB', 'RIFG', 'PWDF')
THEN 1 ELSE 0
END) as cnt1,
SUM(CASE WHEN tbl.from IN ('GGGB', 'GVCE', 'GMWA', 'GTYR') AND
AND tbl.to IN ('GGGBP2', 'GVCEP3', 'GMWAP1', 'GTYRP3')
THEN 1 ELSE 0
END) as cnt2
FROM tbl
WHERE tbl.from IN ('NIVA', 'TIRB', 'RIFG', 'PWDF')
AND tbl.send_date > TRUNC(SYSDATE) - 30
GROUP BY tbl.job_nbr;
use case when, i mean conditional aggregation:
select tbl.job_nbr,
sum(case when tbl.from IN ('NIVA', 'TIRB', 'RIFG', 'PWDF') then 1 else 0 end)
as firstquery_count,
sum(case when tbl.to IN ('GGGBP2','GVCEP3','GMWAP1','GTYRP3' then 1 else 0 end)
as secondndtquery_count
from tbl where tbl.send_date > TRUNC(SYSDATE) - 30
group by tbl.job_nbr
from comments it seems you want add both count so you can use cte
with cte as
(
select tbl.job_nbr,
sum(case when tbl.from IN ('NIVA', 'TIRB', 'RIFG', 'PWDF') then 1 else 0 end)
as firstquery_count,
sum(case when tbl.to IN ('GGGBP2','GVCEP3','GMWAP1','GTYRP3' then 1 else 0 end)
as secondndtquery_count
from tbl where tbl.send_date > TRUNC(SYSDATE) - 30
group by tbl.job_nbr
) select job_nbr,firstquery_count+secondndtquery_count as total
from cte
but with using cte you could do the same with 1st query just by using addition of that two count
From what I understand you need 1 counter, so combine the conditions with OR:
SELECT tbl.job_nbr, COUNT(*) counter FROM tbl
WHERE
tbl.send_date > TRUNC(SYSDATE) - 30
AND
(
tbl.from IN ('NIVA', 'TIRB', 'RIFG', 'PWDF')
OR (
tbl.from IN ('GGGB','GVCE','GMWA','GTYR')
AND
tbl.to IN ('GGGBP2','GVCEP3','GMWAP1','GTYRP3')
)
)
GROUP BY tbl.job_nbr;

TSQL Counting with Nulls

I have a table what counts admited and discharge from ED. This is what the table looks like
I'm trying to get the total admitted and discharged. Something like
Admitted - 100
Discharge - 200
Is there a way to do that with the NULL values?
select
sum(case when Admitted is null then 0 else Admitted end) Admitted,
sum(case when DischargedFromED is null then 0 else DischargedFromED end) as DischargedFromED
from MyMagicalTable;
or
select
sum(coalesce(Admitted, 0)) Admitted,
sum(coalesce(DischargedFromED, 0)) DischargedFromED
from MyMagicalTable;
Just use sum();
select sum(admitted) as admitted, sum(DischargedFromED) as DischargedFromED
from t;
Aggregation functions ignore NULL values.
If you are concerned about NULL values appearing after the sum(), then use coalesce() afterwards:
select coalesce(sum(admitted), 0) as admitted,
coalesce(sum(DischargedFromED), 0) as DischargedFromED
from t;
The above assumes that the columns are numeric. If they are some other type, they need to be converted to numbers.

Query from same table to extract different data

In a single table I have 3 columns. First defines a sector, second count and third amount. I need to extract 5 columns of data in the following manner. First column sector. Second and third to contains the values were amount is less than count and third and four to display were amount is more than count in the specific sectors. How should my query look?
Sample Data - 4 row data for sector one.
1,23,44
1,20,15
1,50,45
1,30,20
Result should be
1,100,80,23,44
You can get it done using a GROUP BY and SUM() aggregate function along with CASE statement like
SELECT sector,
SUM(case when count > amount then count else 0 end) as count1,
SUM(case when amount < count then amount else 0 end) as amount1,
SUM(case when count < amount then count else 0 end) as count2,
SUM(case when amount > count then amount else 0 end) as amount2
FROM mytable
GROUP BY sector;

Choosing one value from partially duplicate rows

I am trying to choose between two rows of data in order to get a total count of type.
Table - Evaluations
EvaluationID (link to minEval_ID and max_EvalID)
EstablishedDelays
Table - Outcome
min_EvalID
max_EvalID
EligTypeRecalc
This is what my current query is:
SELECT "NewEligType"=
COUNT (*),
SUM (CASE WHEN a.EligTypeRecalc IN (1,4,5,7) Then 1 Else 0 END) 'Established Condition',
SUM (CASE WHEN a.EligTypeRecalc=6 Then 1 Else 0 END) 'Established Delay & At-Risk',
SUM (CASE WHEN a.EligTypeRecalc=2 and b.EstablishedDelays=1 Then 1 Else 0 END) 'Established Delay only: One Delay',
SUM (CASE WHEN a.EligTypeRecalc=2 and b.EstablishedDelays=2 Then 1 Else 0 END) 'Established Delay only: Two Delays',
SUM (CASE WHEN a.EligTypeRecalc=2 and b.EstablishedDelays>=3 Then 1 Else 0 END) 'Established Delay only: Three+ Delays',
SUM (CASE WHEN a.EligTypeRecalc=8 Then 1 Else 0 END) 'Clinical Judgement'
from Outcome a
join Evaluations b
on a.max_EvalID=b.evaluationid and a.min_evalID=b.evaluationID
where a.EligTypeRecalc<>3
The problem I'm encountering is picking the correct Eval_ID to choose the correct number of delays and not count the other. The EstablishedDelays associated with max_EvalID is correct unless the EligTypeRecalc is 0, then it should count the delays associated with min_EvalID.
So far I've come up with this basic logic but I'm having a mind block on how to get it to the next step:
CASE WHEN EligTypeRecalc=max_EvalID
THEN EstablishedDelays=max_EvalID
ELSE EstablishedDelays=min_EvalID
Bonus points: I only have Read access to the database.
**What's the proper query syntax to use to select the row associated and exclude the other?
Thanks for your advice!
You might try wrapping your summary of the Evaluations table into a CTE and then join that to the Outcome table.
Here is the code I used, its a little long:
WITH min_eval AS
(
SELECT
a.DataMatch,
a.max_EvalID,
a.EligTypeRecalc,
b.evaluationid,
b.EstablishedDelays
FROM Outcomes a
JOIN Evaluations b
ON a.min_EvalID=b.evaluationid
WHERE a.EligTypeRecalc<>3
),
max_eval AS
(
SELECT
a.DataMatch,
a.max_EvalID,
a.EligTypeRecalc,
b.evaluationid,
b.EstablishedDelays
FROM Outcomes a
JOIN Evaluations b
ON a.max_EvalID=b.evaluationid
WHERE a.EligTypeRecalc<>3
)
SELECT "NewEligType"=
COUNT (*),
SUM (CASE WHEN a.EligTypeRecalc IN (1,4,5,7) THEN 1 ELSE 0 END) 'Established Condition',
SUM (CASE WHEN a.EligTypeRecalc=6 THEN 1 ELSE 0 END) 'Established Delay & At-Risk',
SUM (CASE WHEN (a.EligTypeRecalc=2 AND a.EstablishedDelays=1) OR (a.EligTypeRecalc=2 AND a.EstablishedDelays=0 AND b.EligTypeRecalc=2 AND b.EstablishedDelays=1) THEN 1 ELSE 0 END) 'Established Delay only: One Delay',
SUM (CASE WHEN (a.EligTypeRecalc=2 AND a.EstablishedDelays=2) OR (a.EligTypeRecalc=2 AND a.EstablishedDelays=0 AND b.EligTypeRecalc=2 AND b.EstablishedDelays=2) THEN 1 ELSE 0 END) 'Established Delay only: Two Delays',
SUM (CASE WHEN (a.EligTypeRecalc=2 AND a.EstablishedDelays>=3) OR (a.EligTypeRecalc=2 AND a.EstablishedDelays=0 AND b.EligTypeRecalc=2 AND b.EstablishedDelays>=3) THEN 1 ELSE 0 END) 'Established Delay only: Three+ Delays',
SUM (CASE WHEN a.EligTypeRecalc=8 THEN 1 ELSE 0 END) 'Clinical Judgement'
FROM max_eval a
JOIN min_eval b
ON a.DataMatch=b.DataMatch