SQL CASE Statement Error while checking conditions - mysql

The scenario is that i have two columns one is Quantity and other is Type. Now what i am trying to do is check if type is "rec" then it take all the values from quantity and add them and if the type is "issue" then it will get only those fields whose type is receiving and add them all on the basis of ITEM ID. The SQL Query i have written is here:
SELECT f.`Itemm_ID`,ABS(SUM(f.`Quantity`)) AS recieving, TYPE ,
(CASE
WHEN f.`Type` = 'issue'
THEN ABS(SUM(f.`Quantity`))
END)
FROM stock_journal AS f
WHERE f.`Itemm_ID`='1'
Now the thing is everything is working fine except CASE statement which is returning null.
Please help me in resolving my issue. Thank you

It seems that you need in
SELECT f.`Itemm_ID`,
ABS(SUM(f.`Quantity`)) AS recieving,
TYPE,
ABS(SUM(CASE WHEN f.`Type` = 'issue'
THEN f.`Quantity`
ELSE 0
END))
FROM stock_journal AS f
WHERE f.`Itemm_ID`='1'
PS. Does f.Quantity may be negative? If not then ABS() is excess. If it may then ABS() must wrap inner f.Quantity, not the whole SUM(), maybe.
PPS. TYPE in output is formally incorrect (contradicts with ONLY_FULL_GROUP_BY), I'd recommend wrap it with ANY_VALUE().
i didn't get your recommendation of wrapping type with value can you please elaborate more.
I mean that (maybe, I'm not sure) you need
SELECT f.`Itemm_ID`,
SUM(ABS(f.`Quantity`)) AS recieving,
TYPE,
SUM(CASE WHEN f.`Type` = 'issue'
THEN ABS(f.`Quantity`)
ELSE 0
END)
FROM stock_journal AS f
WHERE f.`Itemm_ID`='1'

Have you checked syntax for CASE I think you are missing ELSE part in the query
Eg:-
SELECT OrderID, Quantity,
CASE
WHEN Quantity > 30 THEN "The quantity is greater than 30"
WHEN Quantity = 30 THEN "The quantity is 30"
ELSE "The quantity is under 30"
END
FROM OrderDetails;
check here for syntax

Related

count and sum in case statement

What is the difference below if I use case instead of sum? I believe I would get the same output?
SELECT SUM(CASE WHEN salary > 100000 THEN 1 ELSE 0 END) AS Total
SELECT COUNT(CASE WHEN salary > 100000 THEN 1 END) AS Total
SELECT COUNT(CASE WHEN salary > 100000 THEN 1 ELSE NULL END) AS Total
Thanks!
Per the other answer, all forms are equivalent. There also a couple of other form that are more compact and achieve the same result:
count_if(salary > 100000)
count(if(salary > 100000, 1))
However, the idiomatic and more general way to do this in Trino (formerly known as Presto SQL) is:
SELECT count(*) FILTER (WHERE salary > 100000) AS Total
FROM ...
See the documentation for more details about filtered aggregations.
All other forms except for the one based on SUM should, per the SQL specification, raise a warning to indicate that null values have been eliminated. This behavior is not yet implemented in Trino, but will be added at some point in the future.
The three are equivalent. All of them count the number of rows that meet the particular condition (salary > 100000). All return 0/1 and would not return NULL values for the column.
From a performance perspective, all should be equivalent as well. I have a personal preference for the first version. I consider the third to be unnecessarily verbose because else NULL is the default for a case expression.

To find the date difference using derived column in mysql

Goal: I want to create a report showing each member experience since joining date with case condition showing 3 categories.
I managed to get the experience(in days) from joining date of the member. trying to derive new column categories say low, med and high. I have tried the below query but it is not working, The below query works for non-date values in reg_date column.
select m.member_id, m.first_name, m.last_name, m.store_id,
(case when m.reg_date<='2018-04-01' then "low"
case when m.reg_date>'2018-04-01' and m.reg_date<='2018-07-31' then "med"
case when m.reg_date>'2018-07-31' then "high"
end, '%y%m%d') as category from member m;
multiple bugs:
syntax should be (case when ... when ... when ...) instead of case for each 'when'.
second argument you pass '%y%m%d' is not necessary.
not a bug, but for the sake of clarity, consider using "else" for the last case.
(case
when m.reg_date<='2018-04-01' then "low"
when m.reg_date>'2018-04-01' and m.reg_date<='2018-07-31' then "med"
else "high"
end)

MySQL - add two dates and set equal to some days

I want to check that lastdate to today is equal to 75 days or not. If it is equal then return 1 else return 0.
I tried below query which gives error-
Select (DATE_ADD(Last_date,CURDATE())=75 DAY) from assessment;
Please give me correct query to get the result-
You need to use CASE expression with DATEDIFF:
Select
CASE WHEN DATEDIFF(Last_date,CURDATE()) = 75 then 1 else 0 END AS col
from assessment
Note that: If last_date might be before or after the CUR_DATE, in this case you will get a negative results. Because:
DATEDIFF() returns expr1 − expr2 expressed as a value in days
So, you might need to get the absolute value of the difference using ABS:
Select
CASE WHEN ABS(DATEDIFF(Last_date,CURDATE()) = 75 then 1 else 0 END) AS col
from assessment
You need to use the MySQL DATEDIFF function
https://www.w3schools.com/sql/func_mysql_datediff.asp

DATEDIFF SQL Query

I am at the final stage of my project and have the problem to find if a job is overdue. I link this to priority for example if a job has a priority of 1 it must be complete in 1 day, a priority of 4 then 4 days.
I have come up with a CASE however this doesn't seem to work any help would be appreciated.
SELECT `defect_Id`,`Overtasked`
WHERE
CASE DATEDIFF(DD,`date_Investigaton` - `CURRENT_DATE()`) >= `priority` AS Overtasked
THEN `Overtasked` == 'YES'
ELSE `Overtasked` == 'NO'
END
Solution
`SELECT defect_Id,
CASE WHEN DATEDIFF(date_Investigated, CURDATE()) >= priority
THEN 'YES'
ELSE 'NO'
END AS Overtasked
FROM defect_report
WHERE defect_Id = '82'`
Appreciate the guidance you guys give!
You are completely mixing up SQL dialects and even there are syntax errors.
Assuming you are talking about MS SQL Server let's try this:
SELECT defect_Id,
CASE WHEN DATEDIFF(DD, date_Investigaton, getdate()) >= priority
THEN 'YES'
ELSE 'NO'
END AS Overtasked
FROM <YourTable>
WHERE <YourWhereIfAny>
If date_Investigation is a DATE column, the subtraction date_Investigation - CURRENT_DATE() produces the number of days you need.
Otherwise (if it is a DATETIME, for example) both operands are converted to float and the result is something you are totally not expecting. For such situations use the DATEDIFF() function. It interprets its arguments as DATE (ignores the time part) and returns the integer number of days between the two dates.
Your query should be like:
SELECT
`defect_Id`,
IF (DATEDIFF(`date_Investigaton`, CURRENT_DATE()) >= `priority`, 'YES', 'NO')
AS `Overtasked`
FROM [...your table name here...]
WHERE [...conditions...]
Replace the parts in square brackets ([...]) with the name of the table where to get the data from and some conditions to limit the number of returned rows (otherwise it will get the entire table which, most probably, is not what you want).
Btw, CURRENT_DATE() is also a function. If you write it in backquotes (``), MySQL will try to find a column with this name and it will fail.
Read the accepted answer for this question. It explains when to use back ticks, single quotes or double quotes in MySQL (and partially in PHP).

MySQL getting total sum of all rows using cases

I have a MySQL table which records values in a database when a user has paid by voucher. It records the voucher value. I need to get a total sum of all voucher values broken down by the voucher amount. The query I currently have is below. However the butchery_class_voucher_155 and butchery_class_voucher_135 are always returned as 0.
Please help to solve this problem.
select
case
when voucher_value = '155.00'
then round(sum(voucher_value/1.2), 2)
else 0.00 end
as butchery_class_voucher_155,
case
when voucher_value = '10.00'
then round(sum(voucher_value/1.2), 2)
else 0.00 end
as shop_voucher,
case when voucher_value = '135.00'
then round(sum(voucher_value/1.2), 2)
else 0.00 end
as butchery_class_voucher_135,
ifnull(round(sum(final_price/1.2), 2),0.00) as paidbycard,
ifnull(round(sum(transfer_fee/1.2), 2),0.00) as transfer_fee
from `bookings`
where `location_id` = 6
The problem is that you have the sum() call within a case, even though the cases (or ifs) should be inside the sum(). With your current code, if the 1st record has a voucher_value of 10, then only the shop_voucher expression will give you any result other than zero.
select
round(sum(if(voucher_value=155,voucher_value/1.2,0)), 2) as butchery_class_voucher_155,
...
from `bookings`
where `location_id` = 6
You need to consider one more thing: where exactly you put your rounding function. You can sum the results first and then round that (this is what is used in my code above), or you can apply the rounding at each and every division.
The reason this is failing is due to the way you have set up your case statement. You've written a query to give you the sum if the voucher_value equals a certain value, or to give you zero. On the last row the query analyzes, it will only compare that voucher value, and the others will return as 0.
To fix this, you need to adjust your SUM() function to add the voucher value in the case that the value matches, otherwise to add 0:
SELECT ROUND(SUM(CASE WHEN voucher_value = 155 THEN (voucher_value / 1.2) ELSE 0 END), 2) AS butchery_class_voucher_155...
And so on.