MySQL IS NULL not working - mysql

Have some ( difficult ) MySQL query
SELECT
*,
(
SELECT
MIN(tbl.id)
FROM
stat tbl
WHERE
tbl.id > stat.id
and tbl.user_id=stat.user_id
) next_session_id,
(
Select
(case
when next_session_id IS NULL then '9999-12-31 23:59:59' else sub.date
end)
from
stat sub
where
sub.id=next_session_id
) next_date
FROM
stat
WHERE
user_id=15973
and date >'2014-06-01'
Problem in next, for last row next_session_id are NULL(check in MySQL Workbench) and it must return datetime '9999-12-31 23:59:59', but return NULL. Check IS NULL not work i think or incorrect. Why it's happen?
UPDATE
Example of result set

You should add OR next_session_id IS NULL to the WHERE clause of your subselect
SELECT
(CASE
WHEN next_session_id IS NULL THEN '9999-12-31 23:59:59' ELSE sub.date
END)
FROM
stat sub
WHERE
sub.id=next_session_id OR next_session_id IS NULL
because without that the where condition will not be true, if next_session is null.

Try changing this part
Select
(case
when next_session_id IS NULL then '9999-12-31 23:59:59' else sub.date
end)
from
stat sub
where
sub.id=next_session_id
to
case
when next_session_id IS NULL then '9999-12-31 23:59:59' else (
Select sub.date
from
stat sub
where
sub.id=next_session_id)
end
Because in MySQL, NULL = NULL doesn't evaluate to true.

In database NULL and '' (empty string) are different. So ensure you have NULL value instead of '' (empty string) in your table.
Check this query with your table
SELECT * FROM TABLE WHERE next_session_id=''

I think IS NULL is not working because of some reason, so you can use = '',
for example x is null you can use x = '' instead.

Related

"IS NOT NULL" not producing the required results in mySQL

I am trying to build a report based of my table. Here is my table:
Following is the SQL query to get desired results.
SELECT
`user`,
SUM(
CASE
WHEN `event_time` >= '2021-04-01 00:00:00'
AND `event_time` <= '2021-04-16 23:59:59'
AND `sub_status` = 'TB'
THEN pause_sec
END
) AS 'Training Break',
SUM(
CASE
WHEN `event_time` >= '2021-04-01 00:00:00'
AND `event_time` <= '2021-04-16 23:59:59'
AND `sub_status` = 'SB1'
THEN pause_sec
END
) AS 'Short Break 1',
SUM(
CASE
WHEN `event_time` >= '2021-04-01 00:00:00'
AND `event_time` <= '2021-04-16 23:59:59'
AND `sub_status` = 'SB2'
THEN pause_sec
END
) AS 'Short Break 2',
SUM(
CASE
WHEN `event_time` >= '2021-04-01 00:00:00'
AND `event_time` <= '2021-04-16 23:59:59'
AND `sub_status` = 'LB'
THEN pause_sec
END
) AS 'Long Break'
FROM
`vicidial_agent_log`
GROUP BY `user`
I am looking to exclude entries which have all null values and following is my syntax but it is not working and produces the same results.
FROM
`vicidial_agent_log`
WHERE 'Training Break' IS NOT NULL
AND 'Short Break 1' IS NOT NULL
AND 'Short Break 2' IS NOT NULL
AND 'Long Break' IS NOT NULL
GROUP BY `user`
Kindly help here or share a post that can help. I have been trying to find but
Don't use single quotes for column names/aliases, because for example 'Training Break' in an expression like 'Training Break' IS NOT NULL is interpreted as a string literal which of course is not null.
In MySql you can use backticks to surround column names.
Also, the columns Training Break, Short Break 1, Short Break 2 and Long Break are the result of aggregate functions so they can't be used in a WHERE clause. Instead use a HAVING clause.
Finally, since you want the rows where at least 1 of these columns is not null you should use the operator OR instead of AND:
FROM
`vicidial_agent_log`
GROUP BY `user`
HAVING `Training Break` IS NOT NULL
OR `Short Break 1` IS NOT NULL
OR `Short Break 2` IS NOT NULL
OR `Long Break` IS NOT NULL
Or:
FROM
`vicidial_agent_log`
GROUP BY `user`
HAVING COALESCE(`Training Break`, `Short Break 1`, `Short Break 2`, `Long Break`) IS NOT NULL
First, move the common part of the SUM() expressions to the WHERE clause.
Second, fix the date logic so you are not missing a second.
I also strongly, strongly recommend using column names that do not need to be escaped. So:
SELECT user,
SUM(CASE WHEN sub_status` = 'TB' THEN pause_sec END) AS Training_Break,
SUM(CASE WHEN sub_status = 'SB1' THEN pause_sec END) AS Short_Break_1,
SUM(CASE WHEN sub_status = 'SB2' THEN pause_sec END) AS Short_Break_2,
SUM(CASE WHEN sub_status = 'LB' THEN pause_sec END) AS Long_Break
FROM vicidial_agent_log
WHERE event_time >= '2021-04-01' AND
event_time < '2021-04-17'
GROUP BY user;
This will probably eliminate the NULL values and speed up the query. However, if there are still NULL values in an entire row, it is because there are rows that don't have one of these statuses. So, just check for them:
SELECT user,
SUM(CASE WHEN sub_status` = 'TB' THEN pause_sec END) AS Training_Break,
SUM(CASE WHEN sub_status = 'SB1' THEN pause_sec END) AS Short_Break_1,
SUM(CASE WHEN sub_status = 'SB2' THEN pause_sec END) AS Short_Break_2,
SUM(CASE WHEN sub_status = 'LB' THEN pause_sec END) AS Long_Break
FROM vicidial_agent_log
WHERE event_time >= '2021-04-01' AND
event_time < '2021-04-17' AND
sub_status IN ('TB', 'SB1', 'SB2', 'LB')
GROUP BY user;
SQL is very powerful in letting you filter before or after aggregation. However, it is usually much better (from a performance perspective) to filter before aggregating.
I also advise you to use identifiers that do not need to be escaped. And, never use single quotes for anything other than string and date literals.

MYSQL returning out of bounds date

I have a DB table with the following structure:
user_id (int) | status (int) | param1 (varchar) | param2 (varchar) | start (date) | external_id (int)
I am doing the following query:
The DB table has the following structure.
select
*
from
`users_stuff`
where
(
`status` >= '8'
and `start` between '2017-07-01' and '2017-07-11'
and `outside_url` is not null
and (
`param1` = '1'
and `param2` = 'A'
)
or (
`param1` = '0'
and `param2` = 'B'
)
and `user_id` = '14'
and `external_id` is not null
)
and `deleted_at` is null
however when the results are returned to me I see items with the "start" set to the 12th of July. Why is that? What is wrong here that would cause that?
Thanks!
I think the placement of the OR condition is casuing this behaviour. I have updated the query as below:
select
*
from
`users_stuff`
where
(
`status` >= '8'
and `start` between '2017-07-01' and '2017-07-11'
and `outside_url` is not null
and (
`param1` = '1'
and `param2` = 'A'
or
`param1` = '0'
and `param2` = 'B'
)
and `user_id` = '14'
and `external_id` is not null
)
and `deleted_at` is null
What is wrong here that would cause that?
Your query looks faulty at first glance and can lead to unexpected behavior, for example you do
`status` >= '8'
however status is int, not s string as you treat it. The same happens for all the other integers which for unknown reasons are quoted in your quest. So fix the syntax and remove all the quotes around integers, so i.e. said
`status` >= '8'
become
`status` >= 8
PS: As small "optimization", I'd move anddeleted_atis null at the beginning of your where clause: wheredeleted_atis null and ... as there's no point evaluating remaining conditions if deleted_at is not null.
Look to your OR stament after AND.
Enclose your OR statement between ().
For example WHERE ( AND criterium OR criterium) AND criterium.

Convertin mysql varchar to number then adding

i have a query with an inner select :
(SELECT SUM(marketing_fee) FROM answer WHERE user_id = m.id AND submit_dt between '2017-02-08 23:59:00' and '2017-02-15 23:59:00') as bookedamount,
the problem is that marketing_fee is a string and can be null, 'null' on any number (but as a string structure).
Is there a way to do a conversion in my select and add them together to get a single total figure that excludes the blanks and nulls?
Thanks
Try this instead:
(SELECT SUM(CASE WHEN marketing_fee is NULL THEN 0 ELSE CONVERT(marketing_fee, INTEGER)) FROM answer WHERE user_id = m.id AND submit_dt between '2017-02-08 23:59:00' and '2017-02-15 23:59:00') as bookedamount
Here's the documentation;
CONVERT
CASE
EDIT 1:
Try this simpler answer:
SELECT SUM(CASE WHEN marketing_fee is NULL OR marketing_fee = '' THEN 0 ELSE marketing_fee) as bookedamount
FROM answer
WHERE user_id = m.id
AND submit_dt between '2017-02-08 23:59:00' and '2017-02-15 23:59:00';

mysql return value even if it is null

I have a query that returns value if the date range is match. and if it is not match it returns nothing.
SELECT start, end
FROM (`taxemployee`)
LEFT JOIN `project_staff_assignment` ON `project_staff_assignment`.`taxemployee_id` = `taxemployee`.`id`
WHERE (start >= '2014-09-01' AND end <= '2014-09-15')
OR (end >= '2014-09-15' AND start <= '2014-09-01')
GROUP BY `taxemployee`.`id`
ORDER BY `assigned_hours`ASC
if I put this on WHERE
OR coalesce(`start`, `end`) IS NULL
it returns null values, but not includes with value
How do I return result even if it is null and with value
here is sqlfiddle
http://sqlfiddle.com/#!2/8bbe4/3
UPDATE:
Refer fiddle here : http://sqlfiddle.com/#!2/2babf/2
I am using case statement to display the date if it falls in the range and am displaying null if not.
SELECT `taxemployee`.`id`, Nickname,
case when project_staff_assignment.startdt >= '2014-09-01' THEN project_staff_assignment.STARTdt ELSE NULL END AS STARTDATE,
case when project_staff_assignment.ENDdt >= '2014-09-15' THEN project_staff_assignment.ENDdt ELSE NULL END AS ENDDATE
FROM (`taxemployee`)
LEFT JOIN `project_staff_assignment` ON `project_staff_assignment`.`taxemployee_id` = `taxemployee`.`id`
GROUP BY `taxemployee`.`id`
ORDER BY `taxemployee`.`id` ASC
ORIGINAL ANSWER:
Refer Fiddle here: http://sqlfiddle.com/#!2/8bbe4/52
SELECT `taxemployee`.`id`, Nickname, start, end
FROM (`taxemployee`)
LEFT JOIN `project_staff_assignment` ON `project_staff_assignment`.`taxemployee_id` = `taxemployee`.`id`
WHERE (start >= '2014-08-01' AND end <= '2014-08-15')
OR (end >= '2014-08-15' AND start <= '2014-09-01')
OR coalesce(`start`, `end`) IS NULL
GROUP BY `taxemployee`.`id`
ORDER BY `taxemployee`.`id` ASC;
Records were not returned because,
Value was available only for 01.08.2014 whereas, your condition was for 01.09.2014

CASE Statement in SQL WHERE clause

I'm trying to fetch data from table where I'm using a CASE condition in the WHERE clause and currently I'm using following query:-
SELECT count(enq_id) AS total, sum(purchase_amount) AS purchase
FROM temp_stock
WHERE purchase_date <> '0000-00-00'
AND purchase_date < '2012-08-01'
AND (
STATUS = 'Sold'
OR STATUS = 'In Stock'
OR STATUS = 'Ref'
)
AND CASE WHEN (
STATUS = 'Sold'
)
THEN delivery_date >= '2012-08-01'
END
But it returns 0 for total and NULL for purchase.
From your comment.
I want to use Case Statement, could u pls clarify me about case statament in where clause
You can use CASE statement in WHERE like this:
SELECT count(enq_id) AS total, sum(purchase_amount) AS purchase
FROM temp_stock
WHERE purchase_date <> '0000-00-00'
AND purchase_date < '2012-08-01'
AND ( STATUS = 'Sold'
OR STATUS = 'In Stock'
OR STATUS = 'Ref')
AND CASE STATUS
WHEN 'Sold'
THEN delivery_date >= '2012-08-01'
ELSE 1=1
END
Here you need to use ELSE 1=1. otherwise you will not get desired result. For more explanation see this SQLFiddle
I don't think that CASE can work that way. What you want is a slightly more complex expression as your WHERE clause. Probably something like this:
SELECT count(enq_id) AS total, sum(purchase_amount) AS purchase
FROM temp_stock
WHERE purchase_date <> '0000-00-00'
AND purchase_date < '2012-08-01'
AND (
(STATUS = 'Sold' AND delivery_date >= '2012-08-01')
OR STATUS = 'In Stock'
OR STATUS = 'Ref'
)