MySQL - SELECT Returns Vague Null Value - mysql

Please take a look at the query :
SELECT Id
FROM TableA
WHERE ColumnA = 'foo'
ORDER BY Id DESC
LIMIT 1
Basically, I want the query to fetch the latest entry on TableA ( Column Id is AI ) with the stated condition ColumnA = 'foo'.
The query will run smoothly and returns what I need. If there is no table entry that will match the condition ColumnA = 'foo', the result is null.
With that being said, I added a CASE to return 1 instead. ELSE, return the Id. Below is the new query:
SELECT CASE
WHEN Id IS NULL
THEN 1
ELSE Id
END
FROM TableA
WHERE ColumnA = 'foo'
ORDER BY Id DESC
LIMIT 1
Using the given query, if the condition is false, there wont be any result. It's blank. Not even NULL.
The question is, why is that? In my perspective, the result should be 1.
Here's a Fiddle link for your testing: http://sqlfiddle.com/#!9/a8e3af/3
Note:
This will work if I use MAX instead of limiting the result to 1. I'm just wondering why this solution will not work.

The ID is never null because no row is returned, and the CASE WHEN will never be executed. A workaround would be like this:
SELECT COALESCE(MAX(ID), 1) AS ID
FROM (
SELECT ID
FROM TableA
WHERE ColumnA = 'G'
ORDER BY Id DESC
LIMIT 1
) s
(an aggregated query will always return a row, with MAX(ID) if an ID is returned or with null if no rows are returned from the subquery)

you can try this it may be useful for you
SELECT IFNULL(Id,1) as ID
FROM TableA
WHERE ColumnA = 'foo'
ORDER BY Id DESC
LIMIT 1

Related

NodeJS, MySQL - Advanced query

"Test" table structure
id
value
itemID
I want to check if in table "Test" there is an result with itemID = '123' and value = '456' and whether it is the last added result ORDER BY id DESC, I miss something in this code:
SELECT * FROM Test WHERE itemID = '123' AND value= '456' ORDER BY id DESC LIMIT 1
Could anyone help?
check if in table Test there is an result with itemID = '123' and value = '456' and whether it is the last added result ORDER BY id DESC
Your requirement can be litteraly translated as follows:
select *
from test t
where itemID = 123 and value = 456
and not exists (
select 1
from test t1
where t1.id > t.id
)
The NOT EXISTS condition ensures that the record being selected is the latest, id-wise.
If the requirements are not satisfied, the query returns an empty resultset.
Another way to express it is to use a correlated subquery to get the latest id:
select *
from test t
where
itemID = 123
and value = 456
and id = (select max(id) from test t)
Using Sub query in where clause you can find it.
SELECT t.* FROM `Test` as t WHERE `itemID` = 123 AND `value` = 456 AND `id` =(SELECT max(`id`) FROM Test);
SELECT (SELECT value
FROM Test
WHERE itemID = '123'
ORDER BY id DESC LIMIT 1) = '456' AS it_matches;
The result will be one of these possibilities:
1 if the last "value" is 456, or
0 if the last "value" is another non-null value, or
NULL if there are no rows with ItemID = 123 or the last row's "value" column is null.

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))

Can I select every row and limit the ones with a diferent value?

Let's say I have a table with columns like this: 'text', 'id' and I want so select all columns that have the id 1 and I want to limit all the columns that have an id of null.
SELECT text, id FROM table_name WHERE id = 1 ..LIMIT 2 WHERE id = null ? ..
I think I have to somehow use a second query, but I don't know really know how ?
SELECT text, id FROM table_name
INNER JOIN (SELECT text, id WHERE id = NULL LIMIT 2) as second ON .. on what
should I join them ? .. WHERE id = 1
How can I select all the columns with the id of one and limit the ones that have an id of null ?
SQL Fiddle
I want to select all rows that have the id of 1 and select only 2 rows where the id is null.
If you use a CTE, then you should be able to limit the results coming back within that CTE(common table expression)
WITH limit AS
(
SELECT id, text FROM table_name WHERE id IS NULL
LIMIT 2
)
SELECT id, text FROM table_name WHERE is = 1
UNION ALL
SELECT * FROM limit;
You want a union.
SELECT text, id FROM table_name WHERE id = 1
UNION ALL
(SELECT text, id FROM table_name WHERE id is null LIMIT 2)
The parentheses are needed to keep the limit from applying to the entire union, not just the second select.

equal and not equal

I have this mysql query which works in getting the specific data by specified date;
SELECT id FROM mytable WHERE DAY(idate)='11' AND MONTH(idate)='01' AND YEAR(idate)='2013' GROUP BY id
now i want to get the data from the date specified and the data outside the date specified, I've tried this query and returns zero results;
SELECT id FROM mytable WHERE DAY(idate)='11' AND DAY(idate)<>'11' AND MONTH(idate)='01' AND YEAR(idate)='2013' GROUP BY id
Your SQL:
SELECT id FROM mytable WHERE DAY(idate)='11' AND DAY(idate)<>'11'
AND MONTH(idate)='01' AND YEAR(idate)='2013' GROUP BY id
is saying "Select the id for the rows from mytable where the day is both equal to 11 and also not equal to 11..."
This is an impossible situation, hence you're getting nothing.
What you actually want is "Select the id for the rows from mytable where the day is equal to 11 as well as the rows where date is not equal to 11...", I think. This is the same as "Select the id for the rows from mytable regardless of the value of the date..." or:
SELECT id FROM mytable WHERE MONTH(idate)='01' AND YEAR(idate)='2013' GROUP BY id
Try OR instead of AND:
SELECT id
FROM mytable t1
WHERE DAY(idate)<>'11'
OR ( DAY(idate) = '11'
AND MONTH(idate)='01'
AND YEAR(idate)='2013'
)
GROUP BY id
you can use your first query and subtract from the queried table, or you can fix your query (read about De-Morgan's laws):
SELECT id
FROM mytable
WHERE DAY(idate)<>'11' OR MONTH(idate)<>'01' OR MONTH(idate)='01' OR YEAR(idate)='2013'
GROUP BY id
Your query at the moment basically has this as a WHERE clause:
where 1 = 1
and 1 <> 1
Obviously both cannot be true. Similarly your filters on DAY(idate) are mutually exclusive. It is difficult to understand exactly what you're trying to achieve. Perhaps you should jyst remove the tests on DAY() altogether?
SELECT id
FROM mytable
WHERE MONTH(idate)='01'
AND YEAR(idate)='2013'
GROUP BY id

Fastest query to see if it returns at least one row

I just need to know if a query returns or not a record.
Of course I can do this:
SELECT COUNT(*) FROM tbl WHERE conds;
But this returns the exact number of rows (of course), and I don't need this overhead.
So I thought this query:
SELECT COUNT(*) FROM (SELECT id FROM tbl WHERE conds LIMIT 1) as t1
Limiting the internal query to 1.
Is this faster? Or considering I am doing a subquery it cancels the benefits of LIMIT 1?
Note: for everyone asking theirself, I can't apply LIMIT 1 to the first query because it doens't work
The inner-select in the second query is redundant.
If you just want to check at-least of one row :-
SELECT 1 FROM tbl // return 1
WHERE conds // depends on your index and query
ORDER BY NULL // avoid file-sort
LIMIT 1; // minimum row
Why not just:
SELECT 1 FROM tbl WHERE conds LIMIT 1
You could do:
SELECT 1 WHERE EXISTS(SELECT id FROM tbl WHERE CONDITION)
Or something like:
SELECT 1 WHERE EXISTS (SELECT id FROM tbl WHERE id IN( 1000, 1001))