CASE STATEMENT + COUNT function not working - SQL Big Query - sql

when i run this code it does not seem to be working in big query...
SELECT date,
COUNT(CASE WHEN product = "fan" AND product color = "white"
THEN product_code ELSE "null" END) AS number_of_whitefans,
FROM `radiant-oven-328313.customer_data.customer_purchase`
GROUP by date
Been trying to run this code many times and i wonder if it's any commas i've missed or just the order of the syntax? i'm running this using bigquery - should i have included a else statement? I've been following the below line of code logic from datacamp so could someone tell me if i've replicated the same thing for my code above with a different data set?
SELECT season,
COUNT(CASE WHEN hometeam_id = 8650
AND home_goal > away_goal
THEN match_id END) AS home_wins
COUNT(CASE WHEN awayteam_id = 8650
AND away_goal > home_goal THEN id END) AS away_wins
From match
GROUP by season;

Related

Output getting a zero for division

As I am trying to calculate 'PUT', when I run the query I get 0 for that field. Any suggestions on how to fix this?
SELECT
COUNT(x_reasons) as Cancel,
week,
COUNT(case when on_plan = '1' then 1 else null end) *1.0 / count(*) AS PUT
FROM inbound.otpu_plan_raw
WHERE
week IN ('43','44','45','46','47','48', '49','50')
AND x_reasons like '%CLOSED%' and code = 'VC'
Group By 1,2
Can someone tell me why I am getting a zero in Put output?

aggregate function error in case expression

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

Using SUM SEC_TO_TIME in MariaDB

Reference from How to sum time using mysql
I want to SUM Field LogsFormatted.Late Every month with query :
SELECT
SUM(CASE
WHEN MONTH (LogsFormatted.DateIn) = 1
THEN SEC_TO_TIME( SUM( TIME_TO_SEC(LogsFormatted.Late)))
ELSE 0 END
) AS '1'
FROM
HrAttLogsFormatted AS LogsFormatted
But the result is
1111 - Invalid use of group function
Where is the problem with the query? resulting in an error output.. Thank you in advance
[EDIT-SOLVED] It's Solved with simply apply
Change format SUM at the beginning of the query
SEC_TO_TIME(SUM(
CASE WHEN MONTH(LogsFormatted.DateIn) = 1 THEN
TIME_TO_SEC(LogsFormatted.Late) END)
) AS '1'
You don't need to call the sum() so many times. You can also move the case condition to the WHERE clause:
SELECT SUM(TIME_TO_SEC(lf.Late))
FROM HrAttLogsFormatted lf
WHERE MONTH(lf.DateIn) = 1 ;
If you want conditional aggregation, then do:
SELECT SUM(CASE WHEN MONTH(lf.DateIn) = 1 THEN TIME_TO_SEC(lf.Late) END)
FROM HrAttLogsFormatted lf;

SQL select grouping and subtract

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

Possible to do math inside of a sum statement?

I'm by no means an expert in DB2 so apologies if this is a novice question. I am looking for a specific requirement. I am summing through a table based on a case statement but am wondering if we could subtract an amount if a field is present in the row.
SELECT CODE,
SUM(CASE SUBSTR(DATE,4,2)
WHEN '01' THEN AMT
END) as JanuaryTotal
FROM Table1
I'm looking to see if we can simply, if another field is present, if we can instead of summing it, simply subtract it from the total that is currently in place.
SELECT CODE,
SUM(CASE SUBSTR(DATE,4,2)
WHEN '01' THEN CASE WHEN TYPE = 'X'
THEN - AMT // some possible way to do this?
ELSE AMT
END) as JanuaryTotal
FROM Table1
Again, apologies. i know this code doesnt run but just giving a visual of something to see if it's possible to do.
SELECT CODE, SUM(
CASE
WHEN SUBSTR(DATE,4,2) = '01' THEN AMT
WHEN TYPE = 'X' THEN 0 - AMT
ELSE AMT
END
) as JanuaryTotal
FROM Table1
Sometimes it helps to indent. Also, it is not quite clear what to do if the sub-string is not 01 -- I'm guessing you don't want to add anything.
SELECT CODE,
SUM(CASE SUBSTR(DATE,4,2)
WHEN '01' THEN
CASE
WHEN TYPE = 'X' THEN -1 * AMT
ELSE AMT
END
ELSE 0 -- SUBSTR(DATE,4,2) is not '01'
END) as JanuaryTotal
FROM Table1
The simplest final query is to flatten out your conditions so they stand alone:
SELECT CODE, SUM(CASE
WHEN SUBSTR(DATE,4,2) AND TYPE = 'X' THEN 0-AMT
WHEN SUBSTR(DATE,4,2) AND THEN AMT END) as JanuaryTotal
FROM Table1
Note that there are two forms of CASE:
CASE <expression>
WHEN <value> THEN ...
WHEN <value> THEN ...
and
CASE
WHEN <condition> THEN ...
WHEN <condition> THEN ...
I switched your query from using the first form to the second form.
SELECT CODE, SUM(
CASE
WHEN SUBSTR(DATE,4,2) = '01' and TYPE = 'X' THEN -AMT
else AMT
END
) as JanuaryTotal
FROM Table1
group by CODE