Replace null with value in mysql query with 0 - mysql

I am trying replace null with 0 with following statement but returns no recrods instead of of catid supplied and 0.
select ifnull(count(*),0) as days, catid from mytable where Id=48 and catId=7
group by mytable.catId;

As far as I know, COUNT(*) does never return NULL. It returns 0 if there is no record.

count(*) never returns NULL, so you don't need any conditional logic:
select count(*) as days, catid
from mytable
where Id = 48 and catId = 7
group by mytable.catId;
Perhaps your issue is that the query is returning no rows. If so, you can leave out the group by. Then the query will always return one row:
select count(*) as days, catid
from mytable
where Id = 48 and catId = 7 ;

Related

MySQL - SELECT a single value from two optional records based on a query param value

Here is my simplified scenario.
I have DB records in 'store_config' table:
ID store_id value
1 0 val1
2 10 val2
3 7 val3
4 99 val4
All records are optional - may or may not exist.
store_id column is unique.
I want to run a query:
WHERE store_id=?
So that:
The query should return a value matching the store_id from the query param if it exists, otherwise return value matching store_id 0 if it exists.
storeId=0 record is considered to be a default value and returned only if there is no existing record for the supplied storeId query param. That's the logic behind it.
You can use order by and limit:
select t.*
from t
where store_id in (#store_id, 0)
order by store_id desc
limit 1;
This assumes (as implied by your question) that there is only one row in the table for each store id. If that is not the case, you might want a more complicated version:
select t.*
from t
where store_id = #store_id
union all
select t.*
from t
where store_id = 0 and
not exists (select 1 from t t2 where t2.store_id = #store_id);
Here is one approach using a LIMIT trick:
SELECT ID, store_id, `value`
FROM store_config
WHERE store_id IN (0, 10)
ORDER BY store_id DESC
LIMIT 1;
The trick here is that if ID=10 is present, then its record would be the one retained. If ID=10 is not present, but ID=0 is present, then this record would be retained. Otherwise, the result set would be empty.
Please try this.
SELECT (IFNULL((SELECT store_id FROM #tbl Where id = #store_id LIMIT 1),0))

Select records from table where a given column value has no non-null values in another column

In this simple table example:
ID SUBID
1000 NULL
1000 NULL
1000 1
1000 NULL
1001 NULL
1001 NULL
I would like my query to return an ID of 1001 only, because all 1001 IDs have NULL in SUBID. 1000 should be excluded, because at least one 1000 ID also has a non-NULL in SUBID.
So something like (convert my plain English to SQL):
select distinct id from table where all records with that id have NULL in subid
You could use a NOT IN the subid where is null
select distinct id
from table
where id NOT IN (
select distinct id from table where subid is null
)
Use a GROUP BY query and check that all SUBID entries are NULL using the BIT_AND() aggregate function:
select ID
from myTable
group by ID
having bit_and(SUBID is null)
Demo: https://www.db-fiddle.com/f/8dnfHV6VVVu7dvoZarTjdp/0
You can also replace the HAVING clause by
having count(SUBID) = 0
since COUNT() will ignore all NULL entries.
Demo: https://www.db-fiddle.com/f/t3FrL7zUAwGqqWDS4dQUg9/0
This version should work for any major RDBMS.
Or
having max(SUBID) is null
This works with most aggregate functions, since they will return NULL, if all entries are NULL. (COUNT() is an exception.)
However - MAX() or MIN() might be the fastest, if you have an index on (ID, SUBID).
You could use a NOT EXISTS clause to check for ID values which have a non-NULL subid value and exclude them from your result:
SELECT DISTINCT m1.ID
FROM myTable m1
WHERE NOT EXISTS (SELECT *
FROM myTable m2
WHERE m2.ID = m1.ID AND m2.subID IS NOT NULL)
Alternatively, you could count the rows associated with the ID value and also count the number of NULL subid values associated with that ID, and see if they are the same:
SELECT ID
FROM myTable m1
GROUP BY ID
HAVING COUNT(*) = SUM(subid IS NULL)
Output:
1001
Demo on dbfiddle

Selecting distinct count in a group with only null values for a specific column

I have 2 columns like this - id and val.
I require such distinct id's where corresponding to each id there is a null value present.
Is it plausible to use "group by" by id and then use "having" clause where null is there?
I would use NOT EXISTS :
SELECT COUNT(DISTINCT id)
FROM table t
WHERE NOT EXISTS (SELECT 1 FROM table t1 WHERE t1.id = t.id AND t1.val IS NOT NULL);
Other option uses the GROUP BY :
SELECT COUNT(id)
FROM table t
GROUP BY id
HAVING SUM(CASE WHEN val IS NOT NULL THEN 1 ELSE 0 END) = 0;
To get ids that have a NULL value, I would be inclined to start with this:
select id
from t
group by id
having count(*) <> count(val);
This structure allows you to check for other values, such as a non-NULL value.
The simplest method to get the distinct ids with NULL values is:
select distinct id
from t
where val is null;
If you only want the count:
select count(distinct id)
from t
where val is null;

MySQL GROUP BY ignore or skip other null column

I have a table:
(id, storage_id, product_id, quantity, property_storage_group_id)
And I need min quantity, but when prouct_id is several, I need to ignore product_id with property_storage_group_id = null.
Something like this:
SELECT MIN(quantity), product_id
FROM storage_quantity
WHERE storage_id = 6
GROUP BY product_id
but without id 22, and with id 27.
You can use a subqueries. Try this:
SELECT MIN(s1.quantity), s1.product_id
FROM storage_quantity s1
WHERE s1.id NOT IN (SELECT s2.id
FROM storage_quantity s2
WHERE s2.product_id = s1.product_id
AND s2.storage_id = s1.storage_id
AND s2.property_storage_group_id IS NULL
AND (SELECT COUNT(s3.property_storage_group_id)
FROM storage_quantity s3
WHERE s3.product_id = s2.product_id
AND s3.storage_id = s2.storage_id
) > 0
)
WHERE s1.storage_id = 6
GROUP BY s1.product_id
The second subquery utilizes the fact that the COUNT() function automatically ignore NULL values, so it only returns the count of property_storage_group_id that are not NULL. If that count is greater than zero, then the first subquery selects all records with property_storage_group_id IS NULL for that product_id. Finally the main query excludes those records returned by the second query.

MySQL - how to select query values which doesn't have a specific data

I'm having some troubles (thinking about it) doing a select from this table.
tb_details:
id status det_id
1 5 22
2 1 22
3 0 22
4 5 25
5 1 25
6 5 27
7 1 27
8 5 32
9 1 32
10 0 32
How can i make a select query to show just the det_id values which doesn't have a 0 in the table, maybe something like this:
det_id
25
27
One approach (out of several workable approaches) is to use an anti-join pattern.
SELECT t.det_id
FROM this_table t
LEFT
JOIN ( SELECT r.det_id
FROM this_table r
WHERE r.status = 0
GROUP BY r.det_id
) s
ON s.det_id = t.det_id
WHERE s.det_id IS NULL
GROUP BY t.det_id
Let's unpack that a bit.
The inline view (aliased as s) returns a distinct list of det_id values for which a status=0 row does exist in this_table.
The LEFT JOIN operation returns all det_id values from this_table t, along with the matching det_id from s. If a match is not found, the "left outerness" of the join means that all rows from t will be returned, whether a match is found or not.
The "trick" is the predicate in the WHERE clause, testing whether the value of the column returned from s is NULL or not. The predicate effectively excludes any rows from t which had a matching row found in s.
So, all that remains to return is rows from t that didn't have a match in s.
We add a GROUP BY t.det_id (or we could add the DISTINCT keyword), to return a list of distinct det_id values.
This isn't the only approach. You could also use a NOT EXISTS predicate ...
SELECT t.det_id
FROM this_table t
WHERE NOT EXISTS
( SELECT 1
FROM this_table r
WHERE r.det_id = t.det_id
AND r.status = 0
)
GROUP BY t.det_id
(This differs slightly, in that a row with a NULL value for det_id could be returned, where the previous query would not return it. That first query could be tweaked to make it return the same result as this.)
You could also use a NOT IN, taking care that the subquery does not return any NULL values for det_id.
SELECT t.det_id
FROM this_table t
WHERE t.det_id NOT IN
( SELECT r.det_id
FROM this_table r
WHERE r.status = 0
AND r.det_id IS NOT NULL
GROUP BY r.det_id
)
GROUP BY t.det_id
There are several statements what will return the specified resultset.
Another and simpler way of doing this is:-
SELECT DISTINCT det_id FROM TB
WHERE det_id NOT IN
(SELECT det_id RFOM TB WHERE status = 0);
If you want to only have the det_id where no other colum is 0 you should write
SELECT det_id FROM TABLE WHERE
Col1 <> 0
AND
Col2 <> 0
and so on...
If you want only 1 result per type add
GROUP BY det_id
at the end of the query.