I am getting an error -
can not nest aggregate operations when trying to run the below part of the query in Teradata.
When SeqCount = 2 and surgery data is the same as the first surgery, I want the 2nd surgery date (SecondSurgery) to be null else return the 2nd surgery data.
Any help would be greatly appreciated.
SELECT
pat_id,
PatientMRN,
PatientName,
AdmitDate,
DischargeDate,
MIN(case when SeqCount=1 then ORProcName else null end) as FirstProcedure,
MIN(case when SeqCount=1 then SurgeryDate else null end) as FirstSurgery,
MIN(case when SeqCount=2 then ORProcName else null end) as SecondProcedure,
MIN(case when SeqCount=2 and SurgeryDate = FirstSurgery then NULL else SurgeryDate end) as SecondSurgery
as the ErrorMsg is saying it's not possible due to the SET-based processing (all at once). - You can force an sequential processing with sub-queries and calculate SecondSurgery in the outer-SQL.
Related
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,
I'm writing a pretty long report, which runs without error, but even though I'm using 'select distinct' it's still showing 11 rows for each unique value i'm trying to report on.
The unique value that I need to display only 1 row per each distinct occurrence is case number, or 'cases.casenum'.
I've included a screenshot of the output which gives a pretty clear idea of what I'm going for... here's the code:
SELECT distinct
(
SELECT count(distinct cases.casenum)
FROM (cases INNER JOIN user_case_data ON cases.casenum=user_case_data.casenum)
WHERE (user_case_data.discharged_date >= '##START##'
AND user_case_data.discharged_date <= '##END##')
)
AS "Total Lost Files", cases.casenum AS "Case Number", user_case_data.discharged_date AS "Discharged Date",
(case when case_notes.topic like 'LOS Case Status Update' THEN case_notes.note_date else null end)
AS "Gendoc #31 Mailed",
(case when case_checklist.code='101' then case_checklist.due_date else null end)
AS "Advised Attorney",
(case when case_notes.topic like 'LOS Updated Lein Ltr' THEN case_notes.note_date else null end)
AS "Sent Updated Lien Ltr",
(case when case_checklist.code='109' then case_checklist.due_date else null end)
AS "Time Allocation Completed",
(case when case_checklist.code='110' then case_checklist.due_date else null end)
AS "Attorney Signed Affidavit",
(case when case_checklist.code='111' then case_checklist.due_date else null end)
AS "Lien Letters Sent",
(case when case_checklist.code='112' then case_checklist.due_date else null end)
AS "Sent Lien to Counsel",
(case when case_checklist.code='113' then case_checklist.due_date else null end)
AS "Received Costs and Transferred"
FROM (cases LEFT JOIN case_checklist ON cases.casenum=case_checklist.case_id
LEFT JOIN user_case_data ON case_checklist.case_id=user_case_data.casenum
LEFT JOIN case_notes ON user_case_data.casenum=case_notes.case_num)
WHERE (user_case_data.discharged_date >= '##START##'
AND user_case_data.discharged_date <= '##END##')
ORDER BY user_case_data.discharged_date ASC;
Additional info:
-Each case number only has 1 discharge date. So for each row, there should be only 1 case number and 1 discharge date.
-There can be many records that exist per case number on the case_notes and case_checklist tables, however I'm only trying to pull the date for 1 single note (with topic specified in case statement), and 1 single checklist item (again specified in case statement)
-The first column isn't really necessary and there's no reason why I want to count the total number of cases for each row... I just wanted a total count somewhere in the output and didn't know how else I could do it.
As suggested by JustinStolle, he was correct in his suggestion for aggregate functions and a GROUP BY:
SELECT
(
SELECT count(distinct cases.casenum)
FROM (cases INNER JOIN user_case_data ON cases.casenum=user_case_data.casenum)
WHERE (user_case_data.discharged_date >= '##START##'
AND user_case_data.discharged_date <= '##END##')
)
AS "Total Lost Files", cases.casenum AS "Case Number", user_case_data.discharged_date AS "Discharged Date",
MAX(case when case_notes.topic like 'LOS Case Status Update' THEN case_notes.note_date else null end)
AS GENDOC_31_Mailed,
MAX(case when case_checklist.code='101' then case_checklist.due_date else null end)
AS ADVISED_ATTORNEY,
MAX(case when case_notes.topic like 'LOS Updated Lein Ltr' THEN case_notes.note_date else null end)
AS "Sent Updated Lien Ltr",
MAX(case when case_checklist.code='109' then case_checklist.due_date else null end)
AS "Time Allocation Completed",
MAX(case when case_checklist.code='110' then case_checklist.due_date else null end)
AS "Attorney Signed Affidavit",
MAX(case when case_checklist.code='111' then case_checklist.due_date else null end)
AS "Lien Letters Sent",
MAX(case when case_checklist.code='112' then case_checklist.due_date else null end)
AS "Sent Lien to Counsel",
MAX(case when case_checklist.code='113' then case_checklist.due_date else null end)
AS "Received Costs and Transferred"
FROM cases
LEFT JOIN case_checklist ON cases.casenum = case_checklist.case_id
LEFT JOIN user_case_data ON case_checklist.case_id=user_case_data.casenum
LEFT JOIN case_notes ON user_case_data.casenum=case_notes.case_num AND case_notes.topic LIKE 'LOS Case Status Update'
WHERE (user_case_data.discharged_date >= '##START##'
AND user_case_data.discharged_date <= '##END##')
GROUP BY cases.casenum, user_case_data.discharged_date
ORDER BY user_case_data.discharged_date ASC;
I have this query
SELECT mylearning.Employee_Id,
case
when max(case when not mylearning.CourseStatusTXT = 'Completed' then 1 else 0 end) = 0 then '2018 Complete'
when max(case when mylearning.CourseStatusTXT in ('Started', 'Not Started') then 1 else 0 end) = 1 then '2018 Not Complete'
end as Completion_Status
FROM Analytics.myLearning_Completions as mylearning inner join Analytics.Workday WD on mylearning.Employee_ID = WD.Employee_ID
And I want to add a condition to the first when statement to make it like this
when max(case when not mylearning.CourseStatusTXT = 'Completed' then 1 else 0 end) = 0
and WD.Adjusted_Hire_Date like '2019% '
and mylearning.CourseTimeCompletedH < cast (WD.Adjusted_Hire_Date as date format 'YYYY/MM/DD') +7
then '2018 Complete'
but I keep getting this error
Executed as Single statement. Failed [3504 : HY000] Selected non-aggregate values must be part of the associated group.
Elapsed time = 00:00:00.069
How can I fix it?
Like a couple others mentioned, you are trying to mix grouped data with non-aggregated data in your calculation, which is why you're getting the 3504 error. You need to either include the referenced columns in your GROUP BY or include them inside an aggregate function (i.e. MAX).
I'm not 100% sure if this is what you're after, but hopefully it can help you along.
SELECT
mylearning.Employee_Id,
CASE
WHEN
MAX(CASE WHEN NOT mylearning.CourseStatusTXT = 'Completed' THEN 1 ELSE 0 END) = 0 AND
WD.Adjusted_Hire_Date like '2019% ' AND
-- Check if most recently completed course is before Hire (Date + 1 week)
MAX(mylearning.CourseTimeCompletedH) <
CAST(WD.Adjusted_Hire_Date AS DATE FORMAT 'YYYY/MM/DD') + 7
THEN '2018 Complete' -- No incomplete learnings
WHEN MAX(
CASE WHEN mylearning.CourseStatusTXT IN ('Started', 'Not Started') THEN 1 ELSE 0 END
) = 1 THEN '2018 Not Complete' -- Started / Not Started learnings exist
END AS Completion_Status
FROM Analytics.myLearning_Completions as mylearning -- Get learning info
INNER JOIN Analytics.Workday WD on mylearning.Employee_ID = WD.Employee_ID -- Employee info
GROUP BY mylearning.Employee_Id, WD.Adjusted_Hire_Date
This will give you a summary per employee, with a couple assumptions:
Assuming employee_ID value in Analytics.Workday is a unique value (one-to-one join), to use WD.Adjusted_Hire_Date in your comparisons, you just need to include it in the GROUP BY.
Assuming you have multiple courses per employee_Id, in order to use mylearning.CourseTimeCompletedH in your comparisons, you'd need to wrap that in an aggregate like MAX.
The caveat here is that the query will check if the most recently completed course per employee is before the "hire_date" expression, so I'm not sure if that's what you're after.
Give it a try and let me know.
The issue here is that you are mixing detail row by row information in the same query as group or aggregated data. Aggregated data will output a single value for all the rows unless you have a group by clause. If you have a group by clause then it will output a single value for each group. When you are grouping you can also include any values that are in the group by clause since they will be unique for the group.
if you want this data for each employee, then you could group by employee_id. Any other data would need to also be an aggregate like Max(Adjusted_Hire_Date)
Maybe this is what you want?
SELECT
mylearning.employee_id
, case
when CourseStatusTXT = 'Completed' and WD.Adjusted_Hire_Date like '2019%'
and mylearning.CourseTimeCompletedH < cast (WD.Adjusted_Hire_Date as date format 'YYYY/MM/DD') +7
then '2018 Complete'
else '2018 Not Complete'
end CompletionStatus
FROM myLearning_Completions mylearning, Workday WD
WHERE mylearning.employee_id = WD.employee_id
i have table named source table with data like this :
And i want to do query that subtract row with status plus and minus to be like this group by product name :
How to do that in SQL query? thanks!
Group by the product and then use a conditional SUM()
select product,
sum(case when status = 'plus' then total else 0 end) -
sum(case when status = 'minus' then total else 0 end) as total,
sum(case when status = 'plus' then amount else 0 end) -
sum(case when status = 'minus' then amount else 0 end) as amount
from your_table
group by product
There is another method using join, which works for the particular data you have provided (which has one "plus" and one "minus" row per product):
select tplus.product, (tplus.total - tminus.total) as total,
(tplus.amount - tminus.amount) as amount
from t tplus join
t tminus
on tplus.product = tminus.product and
tplus.status = 'plus' and
tplus.status = 'minus';
Both this and the aggregation query work well for the data you have provided. In other words, there are multiple ways to solve this problem (each has its strengths).
you can query as below:
select product , sum (case when [status] = 'minus' then -Total else Total end) as Total
, sum (case when [status] = 'minus' then -Amount else Amount end) as SumAmount
from yourproduct
group by product
I have a table billing_history which consists of the following fields
CREATE TABLE [dbo].[BILLING_HISTORY2](
[ID] [int] IDENTITY(1,1) NOT NULL,
[READING_MONTH_YEAR] [date] NULL,
[READING] [int] NULL,
[CONSUMER_ID] [int] NULL,
[payment_status] [bit] NOT NULL
)
http://www.sqlfiddle.com/#!3/892e0/5
The following queries return the MAX Paid And Max Unpaid Values for a Consumer
SELECT MAX(READING) AS 'MAXIMUM_PAID_READING',consumer_id from billing_history2
where payment_status=0 GROUP BY consumer_id;
SELECT MAX(READING) AS 'MAXIMUM_UNPAID_READING',consumer_id from billing_history2
where payment_status=1 GROUP BY consumer_id;
However when i join them to subtract the MAXIMUM_PAID_READING from MAXIMUM_UNPAID_READING to get the current reading, by joining the above two queries, it results in returning all those records which have a matched consumer_id. So if a consumer hasn't paid any bill yet, the id would be omitted in the PAID_READING and hence an INNER JOIN doesn't return any result. IF i use FULL OUTER JOIN, it return all the records but sets the difference to NULL.
I need to find out the current USAGE of the customer by subtracting it from the previous unpaid USAGE.
How do i go about joining these two queries in such a way that the resulting difference is found irrespective whether the person has paid a bill in the past or not.
Don't join them.
SELECT
MAX(CASE WHEN payment_status=0 THEN READING ELSE NULL END) AS 'MAXIMUM_PAID_READING',
MAX(CASE WHEN payment_status=1 THEN READING ELSE NULL END) AS 'MAXIMUM_UNPAID_READING',
MAX(CASE WHEN payment_status=0 THEN READING ELSE NULL END)
- MAX(CASE WHEN payment_status=1 THEN READING ELSE NULL END)
AS 'DIFF_READING',
consumer_id from billing_history2
GROUP BY consumer_id;
If you want handle NULL values from MAX function, use ISNULL function:
SELECT
ISNULL(MAX(CASE WHEN payment_status=0 THEN READING ELSE NULL END),0) AS 'MAXIMUM_PAID_READING',
ISNULL(MAX(CASE WHEN payment_status=1 THEN READING ELSE NULL END),0) AS 'MAXIMUM_UNPAID_READING',
ISNULL(MAX(CASE WHEN payment_status=0 THEN READING ELSE NULL END),0)
- ISNULL(MAX(CASE WHEN payment_status=1 THEN READING ELSE NULL END),0)
AS 'DIFF_READING',
consumer_id from billing_history2
GROUP BY consumer_id;
It's ok to use left outer join, but use isnull on your max value.
ex:
max(...) - isnull(max(...),0) as ...
In your case is necessary to use CASE expression
SELECT CONSUMER_ID,
MAX(CASE WHEN payment_status = 0 THEN READING ELSE 0 END) AS 'MAXIMUM_PAID_READING',
MAX(CASE WHEN payment_status = 1 THEN READING ELSE 0 END) AS 'MAXIMUM_UNPAID_READING',
MAX(CASE WHEN payment_status = 0 THEN READING ELSE 0 END) -
MAX(CASE WHEN payment_status = 1 THEN READING ELSE 0 END) AS diff
FROM billing_history2
GROUP BY consumer_id
Demo on SQLFiddle