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
Related
"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.
I'm trying to get values from the database based on two values of my own, the values must match the id of the database
id contactid flag flag_type
-----------------------------------
1 99 Volunteer 1
2 99 Uploaded 2
3 100 Via Import 3
4 100 Volunteer 1
5 100 Uploaded 2
So from here I would want to get the rows with the id's 1 and 2, and ignore the rest of the values. But say for example that the row with the id 2 does not exist the statement would not return any row.
I've tried the following statement, but it doesn't seem to work :
SELECT * FROM docs WHERE id IN (1) AND id IN (2);
You should use OR
SELECT * FROM docs
WHERE id IN (1) OR id IN (2);
or
SELECT * FROM docs
WHERE id = 1
OR id = 2;
or if you need the records for contactid with both id (1,2) then
select * from docs
inner join (
select contactid
from docs
where id IN (1, 2)
having count(distinct id ) = 2
) t on t.contactid = docs.contactid
you need subquery
select id from table_name where contactid in (
select contactid
from table_nae
group by contactid
having count(*)=2
)
subquery will pick only those contactid whose count is two and in condition of main query will help to pick your desired id
If you want the contacts with exactly those flags, you can do:
select contactid
from t
group by contactid
having sum(flag = 1) > 0 and -- has 1
sum(flag = 2) > 0 and -- has 2
sum(flag not in (1, 2)) = 0; -- has nothing else
There are various ways to get the original rows -- using in or exists or join:
select t.*
from t join
(select contactid
from t
group by contactid
having sum(flag = 1) > 0 and -- has 1
sum(flag = 2) > 0 and -- has 2
sum(flag not in (1, 2)) = 0 -- has nothing else
) tt
on t.contactid = tt.contactid;
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.
Sample table:
id------user_id------grade_id------time_stamp
1---------100----------1001---------2013-08-29 15:07:38
2---------101----------1002---------2013-08-29 16:07:38
3---------100----------1001---------2013-08-29 17:07:38
4---------102----------1003---------2013-08-29 18:07:38
5---------103----------1004---------2013-08-29 19:07:38
6---------105----------1002---------2013-08-29 20:07:38
6---------100----------1002---------2013-08-29 21:07:38
I want to select rows whose user_id = 100 group by grade_id only if its time_stamp is least for that particular grade_id.
so, from the above table, it should be:
row 1 because its time_stamp is least for that value of grade_id(1001)
but not row 2 because I only want 1 row for a particular grade_id
also not row 6 because that particular grade_id has least value for user_id 105.
I tried few things, which are too basic and obviously not worth posting.
Thank You
You could try nested queries:
SELECT grade_id, COUNT(grade_id) FROM SAMPLE_TABLE ST WHERE time_stamp = (SELECT MIN(time_stamp) FROM SAMPLE_TABLE STT WHERE STT.grade_id = ST.grade_id) AND user_id = 100 GROUP BY grade_id;
In this case, the nested query will give you the minimun timestamp for each specific 'grade_id' and you can use it in your WHERE filter.
SELECT t.*
FROM tableX AS t
JOIN
( SELECT grade_id, MIN(time_stamp) AS time_stamp
FROM tableX
GROUP BY grade_id
) AS g
ON g.grade_id = t.grade_id
AND g.time_stamp = t.time_stamp
WHERE t.user_id = 100 ;
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