NodeJS, MySQL - Advanced query - mysql

"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.

Related

Using if() in a where clause

I need to do an if else on a where clause.
I want to do something like
Select id from table where if(client_id = 10, client_id = 10, client_id = 1) AND foo = A
In clear I need
if client_id 10 exist where foo = A return id
else
client_id 10 doesn't exist where foo = A
use client_id = 1 where foo = A
I don't think you need an IF. You could try with this query:
SELECT id FROM table WHERE client_id in (10,1) AND foo='A';
EDIT:
Query example 1:
SELECT IF(client_id=10 AND foo='A',id,'') AS '10A',
IF(client_id <> 10 AND client_id=1 AND foo='A',id,'') AS '1A'
FROM table HAVING (10A OR 1A) <> '';
Query example 2:
SELECT id
FROM table
WHERE
client_id=CASE WHEN client_id=10 AND foo='A' THEN client_id
WHEN client_id <> 10 AND client_id=1 AND foo='A' THEN client_id
END;
Query example 3:
SELECT id
FROM table
WHERE
client_id=IF(client_id=10 AND foo='A',client_id,
IF(client_id <> 10 AND client_id=1 AND foo='A',client_id,''));
The last example could be what you initially have in mind.

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 - SELECT Returns Vague Null Value

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

select where id == value and id != value mysql

I have a table with values like this
listid email
1 test#email.com
5 test#eamil.com
1 test123#email.com
From the above example you can see that the same email can show up in the email column with a different listid.
I want to return emails that have a listid of 1 but not not also have a listid of 5. In that case the only email returned would be test123#email.com.
For now I have
SELECT `email`,`listid` FROM `table` WHERE `emailaddress` LIKE '%#email%' AND `listid` != 5 AND `listid`=1
Of course this does not work because test#email does have a listid of 1 too. How can I exclude test#email from the results?
You could use the exists operator:
SELECT `email`,`listid`
FROM `table` t
WHERE `emailaddress` LIKE '%#email%' AND
`listid` = 1 AND
NOT EXISTS (SELECT *
FROM `table` t2
WHERE t1.`emailaddress` = t2.`emailaddress` AND
t2.`listid = 5)
You could use a join:
SELECT t.email, t.listid
FROM `table` t
JOIN `table` t2 ON t.email = t2.email AND t2.listid != 5
WHERE t.listid = 1
Here's a way using conditional aggregation that's generally fast. The query selects emails with listid 1 or 5, and uses conditional aggregation to remove emails that have listid 5 and returns emails that only have listid 1.
select email
from mytable t
where email LIKE '%#email%'
and listid in (1,5)
group by email
having sum(listid = 5) = 0
This query can take advantage of an index on listid

MySQL - Matching 2 rows (or more!) within a sub-query/table

I have this schema which I need to match 2 rows from
user_data : user_id, field_id, value
A sample output would be:
user_id field_id value
-----------------------------
1 1 Gandalf
1 2 Glamdring
How do I write a query which basically say "Find the user id of the user whose field_id 1 is Gandalf, and field_id 2 is Glamdring?"
SELECT FROM looks at one row at a time. I am stumped on this. I will also need to find a solution that scale gracefully (such as looking at three rows etc.)
You could run a query to get the users that match each of the conditions and intersect the results. Since MySQL doesn't support intersect you can do it with an n-way join:
SELECT T1.user_id
FROM Table1 T1
JOIN Table1 T2 ON T1.user_id = T2.user_id
WHERE T1.field_id = 1 AND T1.value = 'Gandalf'
AND T2.field_id = 2 AND T2.value = 'Glamdring'
I would try the following:
SELECT user_id
FROM user_data
WHERE ( field_id = 1 AND value= 'Gandalf' )
OR ( field_id = 3 AND value = 'Glamdring' )
GROUP BY user_id
HAVING COUNT( field_id ) = 2
It will search for all the rows that match one of your criteria, and use GROUP BY and HAVING afterwards to find the user_id that has the expected count of matches.
select * from user_date where ( field_id= 1 AND value='Gandalf' ) OR ( field_id =2 AND value ='Glamdring' ) ;
The HAVING clause is the key. It turns the query from an "OR" statement into an "AND" statement