No results even by using EXISTS - mysql

I don't undersand why MySQL returns "MySQL did not produce a record" whereas I use EXISTS (I willingly chose a subquery which doesn't produce records) :
SELECT page_ID
FROM ranks_update
WHERE EXISTS (
SELECT *
FROM ranks_update
WHERE ranking_ID = 3
AND current_rank = 1
AND rating_time < '2012-08-05 02:57:59'
AND rating_time >= '2012-08-05 00:00:00'
GROUP BY page_ID
);
By definition EXISTS allows to get a result from a query which doesn't return any records. Until now I've always got NULL in such case.

It is returning that message because no records match. NULL is a value for a column. It is quite different from an empty return set.
If you have an aggregate function, then the empty set returns a NULL. So the following would return a NULL value:
select max(Page_ID)
and this would return 0:
select count(Page_ID)

Related

SQL Bind multiple fields condition as AND clause

Can someone help me with this SQL.
Output must always join the day_ids as multiple condition.
For instance, if we choose day_id IN (0,2,4), it must return ONLY all data with day_ids (0,2,4). It works fine.
So when we input (0,2,4,5), it must not return any data. This is where the issue occurs.
Since IN clause follows the OR statement, it still gives the same result instead of returning NULL.
Sample data: https://drive.google.com/file/d/1rXjOPxFRmtDjdyD4bDvULP-m38G5GvIB/view
Video : https://drive.google.com/file/d/1WM42cmmMe1nCusqacJNS_MI2t9szgZGn/view?usp=sharing
Any idea will be greatly appreciated.
https://i.stack.imgur.com/lWfdy.png
https://i.stack.imgur.com/s0Ala.png
SELECT * FROM vw_transfer_sched WHERE day_id in (0,2,4,5)
GROUP BY week_num, day_id, teacher_id
HAVING COUNT(distinct day_id) = 4;
SELECT * FROM vw_transfer_sched CASE WHEN day_id IN (0,2,4) THEN day_id ELSE Null END;
That should give you Null if there are no rows containing 0,2,4
Instead of sending your desired must exits day_ids to the query, you can find out if all those day_ids exist with help of a different query and compare it outside and if they all exist then you can run the query that you have attached.
You can compare the result of the following query with your desired must exist day_ids.
select group_concat(distinct day_id)
from teacher_availability_list
where day_id in (0,2,4,5)
With the table that you have attached it will return 0,2,4.
you can do this outside of the query or in a stored procedure.
IF (result of the above query) = the desired must have day_ids
then -> run the query
else
return null
try
select t.*
from
( SELECT *
FROM teacher_availability_list
GROUP BY week_num, teacher_id, day_id
order by week_num, teacher_id ) as t
group by week_num, teacher_id
having group_concat(t.day_id)='0,1,2'

If value exists in other table, return another value from that table

I currently have the following SQL query:
SELECT video_calls.initiated_user_id AS user_id,
(CASE
WHEN EXISTS
(SELECT *
FROM patients
WHERE patients.id = video_calls.initiated_user_id)
THEN 'patient'
ELSE (CASE
WHEN EXISTS
(SELECT *
FROM backend_users
WHERE backend_users.id = video_calls.initiated_user_id)
THEN "%%backend%%"
ELSE "unknown"
END)
END) AS user_type
FROM video_calls
WHERE id='7f350a98-93d3-4d21-80a8-6cda3e47a4c0'
UNION
SELECT user_id,
user_type
FROM channel_joins
WHERE channel_id='7f350a98-93d3-4d21-80a8-6cda3e47a4c0'
In the line, where it currently says THEN "%%backend%%" I'd like to return the column backend_users.backend_type instead, for the corresponding row where the value video_calls.initiated_user_id has been found. I suppose I need to work with a JOIN here, but I currently can't figure out where exactly.
You are already using a correlated subquery. You can use that to get the value:
ELSE (SELECT COALESCE(MAX(bu.backend_type), 'unknown')
FROM backend_users bu
WHERE bu.id = video_calls.initiated_user_id
)
Note the use of MAX(). This ensures that exactly one value is returned. If no rows match, the MAX() returns NULL, so 'unknown' is returned.
This has one slight nuance from your pseudo-code. If the matching row is NULL, then this returns 'unknown' rather than NULL. If that is an issue, the logic in the subquery can be tweaked.

sub query returns more than 1 - issue with passing values into subquery

I am running the following query which keep stating that more then one row is given:
select filestorage.id
from `filestorage`
where (SELECT LEFT(filestorage_inst_data.value, length(filestorage_inst_data.value - 1)) as seconds
FROM filestorage_inst_data
WHERE filestorage_inst_data.parameter = "Time" AND filestorage_inst_data.filestorage_id = filestorage.id) <= 3600
For some reason, the only very first value is passed into the subquery. Also, if I do set a limit within the subquery than the data is fetched fine, it's just I don't see why query would fetch multiple results?
Try this:
SELECT filestorage.id
FROM filestorage f
WHERE EXISTS(SELECT 1 FROM filestorage_inst_data fid
WHERE fid.parameter = 'Time'
AND fid.filestorage_id = f.id
AND CAST(LEFT(fid.value, length(fid.value - 1)) AS UNSIGNED) <= 3600)
You have to pass a specific one row when giving a select statement on where clause. select clause that, the one you using on where clause must return one unique row. for example.
"SELECT * FROM user WHERE role_id=(SELECT role_id FROM user_role WHERE role_name='Admin');"

Subqueries with EXISTS vs IN - MySQL

Below two queries are subqueries. Both are the same and both works fine for me. But the problem is Method 1 query takes about 10 secs to execute while Method 2 query takes under 1 sec.
I was able to convert method 1 query to method 2 but I don't understand what's happening in the query. I have been trying to figure it out myself. I would really like to learn what's the difference between below two queries and how does the performance gain happen ? what's the logic behind it ?
I'm new to these advance techniques. I hope someone will help me out here. Given that I read the docs which does not give me a clue.
Method 1 :
SELECT
*
FROM
tracker
WHERE
reservation_id IN (
SELECT
reservation_id
FROM
tracker
GROUP BY
reservation_id
HAVING
(
method = 1
AND type = 0
AND Count(*) > 1
)
OR (
method = 1
AND type = 1
AND Count(*) > 1
)
OR (
method = 2
AND type = 2
AND Count(*) > 0
)
OR (
method = 3
AND type = 0
AND Count(*) > 0
)
OR (
method = 3
AND type = 1
AND Count(*) > 1
)
OR (
method = 3
AND type = 3
AND Count(*) > 0
)
)
Method 2 :
SELECT
*
FROM
`tracker` t
WHERE
EXISTS (
SELECT
reservation_id
FROM
`tracker` t3
WHERE
t3.reservation_id = t.reservation_id
GROUP BY
reservation_id
HAVING
(
METHOD = 1
AND TYPE = 0
AND COUNT(*) > 1
)
OR
(
METHOD = 1
AND TYPE = 1
AND COUNT(*) > 1
)
OR
(
METHOD = 2
AND TYPE = 2
AND COUNT(*) > 0
)
OR
(
METHOD = 3
AND TYPE = 0
AND COUNT(*) > 0
)
OR
(
METHOD = 3
AND TYPE = 1
AND COUNT(*) > 1
)
OR
(
METHOD = 3
AND TYPE = 3
AND COUNT(*) > 0
)
)
An Explain Plan would have shown you why exactly you should use Exists. Usually the question comes Exists vs Count(*). Exists is faster. Why?
With regard to challenges present by NULL: when subquery returns Null, for IN the entire query becomes Null. So you need to handle that as well. But using Exist, it's merely a false. Much easier to cope. Simply IN can't compare anything with Null but Exists can.
e.g. Exists (Select * from yourtable where bla = 'blabla'); you get true/false the moment one hit is found/matched.
In this case IN sort of takes the position of the Count(*) to select ALL matching rows based on the WHERE because it's comparing all values.
But don't forget this either:
EXISTS executes at high speed against IN : when the subquery results is very large.
IN gets ahead of EXISTS : when the subquery results is very small.
Reference to for more details:
subquery using IN.
IN - subquery optimization
Join vs. sub-query.
Method 2 is fast because it is using EXISTS operator, where I MySQL do not load any results.
As mentioned in your docs link as well, that it omits whatever is there in SELECT clause. It only checks for the first value that matches the criteria, once found it sets the condition TRUE and moves for further processing.
On the other side Method 1 has IN operator which loads all possible values and then matches it. Condition is set TRUE only when exact match is found which is time consuming process.
Hence your method 2 is fast.
Hope it helps...
The EXISTS operator is a Boolean operator that returns either true or false. The EXISTS operator is often used the in a subquery to test for an “exist” condition.
SELECT
select_list
FROM
a_table
WHERE
[NOT] EXISTS(subquery);
If the subquery returns any row, the EXISTS operator returns true, otherwise, it returns false.
In addition, the EXISTS operator terminates further processing immediately once it finds a matching row. Because of this characteristic, you can use the EXISTS operator to improve the performance of the query in some cases.
The NOT operator negates the EXISTS operator. In other words, the NOT EXISTS returns true if the subquery returns no row, otherwise it returns false.
You can use SELECT *, SELECT column, SELECT a_constant, or anything in the subquery. The results are the same because MySQL ignores the select_list that appears in the SELECT clause.
The reason is that the EXISTS operator works based on the “at least found” principle. It returns true and stops scanning table once at least one matching row found.
On the other hands, when the IN operator is combined with a subquery, MySQL must process the subquery first and then uses the result of the subquery to process the whole query.
The general rule of thumb is that if the subquery contains a large volume of data, the EXISTS operator provides a better performance.
However, the query that uses the IN operator will perform faster if the result set returned from the subquery is very small.
For detail explanations and examples: MySQL EXISTS - mysqltutorial.org
The second Method is faster because you've got this like there "WHERE t3.reservation_id = t.reservation_id". In the first case your subquery has to do a full scan into the table to verify the information. However at the 2o Method the subquery knows exactly what it is looking for and once it is found is checked the having condition then.
Their Official Documentation.SubQuery Optimization with Exists

mysql return single result from single table with complex condition

I have this table :
table(fied1 int,field2 int,field3 varchar(40));
I would like to obtion without a stored procedure something like:
declare int nr default 0;
select coalesce(max(field1),0) into nr from table where field2=? and field3=?;
if(nr = 0) then
select coalesce(max(field1),0)+1 into nr from table;
end if;
i want the value of nr from single select.
pls help !!!
Only use the following query to get one plus to last inserted value in field1 column if no match found as per where clause else it returns the max value stored in field1:
This query is handling the case if there are no records in table.
the filter crieteria "and field1<>0" in following statement is required if field1 can have value 0 also otherwise remove this filter (and field1<>0) from following query
Select coalesce(
max(field1),
(select coalesce(max(field1),0)+1 from table)
)
from table where field2=? and field3=? and field1<>0;
I think this captures your requirements:
SELECT
CASE
WHEN (max(field1) IS NULL OR max(field1) = 0) AND field2=? AND field3=? THEN (max(field1)+1)
ELSE max(field1)
END AS `field1_max`
FROM table