How to query not available value in the column? - mysql

I've a table as follows:
From this, I'm trying to get the user_id's where status IS NOT STATUS 4 AVAILABLE . In other word the results I'm expecting are:
User Ids: 17, 19 and 20.
I tried many queries but nothing didn't worked for me. For example I tried.
SELECT user_id WHERE status NOT IN (4)
The above above query still returns as follows:
User Ids: 1, 17, 18, 19 and 20.
I know the reason why it's returning but I'm not sure how to overcome the problem.
Any help would be appreciated.

You are going to need to do a subquery for this. For example:
Select user_id from table Where user_id not in
(select user_id from table where status = 4 and user_id is not null);
This allows you to exclude all user_id's that are in a status of 4.

Try this:
SELECT user_id
FROM mytable
GROUP BY user_id
HAVING COUNT(CASE WHEN status = 4 THEN 1 END) = 0
or, alternatively:
SELECT user_id
FROM mytable AS t1
WHERE NOT EXISTS (SELECT 1
FROM mytable AS t2
WHERE t1.user_id = t2.user_id AND status = 4)

Related

Get rows where the specific value is present and if its not there then display the one with other value

I have a condition when user changes his mail id the status column value changes to 100. If the mail id is not changed then the value in status column will be 10. The id will be the same always for a user.
ID MAIL Status
10248 xyz#xyz.com 10
10248 xyz1#xyz.com 100
10241 abc#abc.com 10
10249 pqr#pqr.com 10
10249 pqr1#pqr.com 100
10250 kbc#kbc.com 10
10251 axc#axc.com 10
So, from this if the mail id has been changed then get the row with the new mail id. Like if status 100 is present for a id then display the row of that id and don't display status 10 row for that id. If there is no status 100 for a id then display row with status 10.
I tried this but it returns both the status for a id.
SELECT id, mail, IF(status=100, status=100,status=10)
FROM table1;
so, for ID 10248 and 10249, I expect only the row with status 100.
From what I understand, here's what you're trying to do:
if there is a row for a user with status code = 100, return that row
otherwise, return the row with status code = 10
If your version (8.0+) supports window functions, you can do something like this:
SELECT id, mail
FROM (
SELECT id, mail,
ROW_NUMBER() OVER(
PARTITION BY id ORDER BY
CASE status
WHEN 100 THEN 0 -- Give status = 100 first priority
WHEN 10 THEN 1 -- Give status = 10 second priority
ELSE 2 -- Give anything else last priority
END
) AS RowNum
FROM table1
) src
WHERE RowNum = 1
How about this? :)
SELECT t1.ID , t1.MAIL, (
SELECT t2.Status
FROM table1 as t2
WHERE t2.ID = t1.ID -- connect
DESC t2.Status DESC -- show latest
LIMIT 1 -- get only TOP
) as currentstat
FROM table1 as t1
GROUP BY t1.ID
Will show 100 if 100 exists.
Will show 10 if 100 did not exist. :)
I Guess This Code will Help you get your Required Result
SELECT id,mail,Status
FROM (
SELECT id,mail,Status, ROW_NUMBER() over(partition by id order by Status desc)RN FROM #temp
)m
WHERE m.RN = 1
if you would not create procedure and don't have ORM:
select b.id,b.mail,b.status from table1 b
left join (
select a.id,max(a.status) as status from table1 a
group by a.id) c on c.id = b.id
where c.status=b.status
mysql version 5.8 not needed for this query
You can use union as below, First we are collecting if status 100 is present for a id then we collect other status value, means whose email id is not changed yet and status is still 10
select * from test where Status = 100
union
select t.*
from test t
left join test t1 on t1.id = t.id
and t1.Status = 100
where t1.id IS NULL

MySQL check if comma separated values match rows in table

I'm trying to figure out how I can query my table to see if a group of user_id's match a conversation_id.
Query 1 should return result for:
user_id 1 is looking to see if there are any conversation_id's with just user_id = 2 and user_id = 1 in it. (Should return a row for each conversation_id = 1, 2, 4, 5 based on SQL Fiddle example)
conversation_id
1
2
4
5
Query 2 should return result for:
user_id 1 is looking to see if there are any conversation_id's with user_id = 2, user_id = 1, and user_id = 4 in it. (Should return 0 rows as it doesn't exist in the SQL Fiddle example)
The table setup is located at
SQL Fiddle
You can use a combination of group by ... having and a correlated exists subquery to achieve the result you want:
-- Query 1:
SELECT
conversation_id
FROM
users_conversations uc
where not exists (
select 1 from users_conversations
where conversation_id = uc.conversation_id
and user_id not in (1,2)
)
group by conversation_id
having count(distinct user_id) = 2;
-- Query 2: same query, only different numbers.
SELECT
conversation_id
FROM
users_conversations uc
where not exists (
select 1 from users_conversations
where conversation_id = uc.conversation_id
and user_id not in (1,2,4))
group by conversation_id
having count(distinct user_id) = 3;
Sample SQL Fiddle
Note that the first query will not return 1,2,4,5 but rather 2,5 but in your sample data neither 1 or 4 has only user_id 1 and 2 as participants (conversation 1 has 1,2,3,4, and conversation 4 has 1,2,5).
If i understand it right it should be something like his.
Q1:
SELECT
CASE
WHEN
count(distinct CASE WHEN user_id in ('1','2') THEN user_id END)>='2'
THEN `conversation_id`
END 'test'
FROM
users_conversations
where 1
group by `conversation_id`
Q2:
SELECT
CASE
WHEN
count(distinct CASE WHEN user_id in ('1','2','4') THEN user_id END)>='3'
THEN `conversation_id`
END 'test'
FROM
users_conversations
where 1
group by `conversation_id`
http://sqlfiddle.com/#!9/fb29d/9

What SQL statement have to use to get list of non duplicate id's from 1 table, but 2 columns

Have a table for chat where I collect user_from, user_to and other non important stuffs for the example.
Want to get user_id's for all the users related in conversation (with where clause for current user_id).
In the example below I'm trying to search all the users where user_id=1 exist, but I know that doesn't work and don't know how to make it works.
SELECT *
FROM messages M
WHERE M.user_from="1" OR M.user_to="1"
GROUP by m.user_from, m.user_to
If in table are rows (below). Actually I want to receive finally array([0]=>2, [1]=>4), because user_id=1 have conversation only with user_id=2 and user_id=4
user_from | user_to
1 2
1 2
2 1
1 4
3 2
Probably I have to use Select in the Select or use anykind of Case When Then, but have no idea how to loop it correctly
RESOLVED WITH ORDERING BY LAST MSG_ID!!!
SELECT (IF( user_from = 1, user_to, user_from )) as user_id
FROM messages
WHERE `user_from` = 1 OR `user_to` = 1
GROUP BY user_id
ORDER BY MAX(msg_id) DESC
select user_to as user_id
from messages
where user_from = 1
union
(select user_from as user_id
from messages
where user_to = 1)
edited on suggestion from #Анжел Миленов - (I do not personally know why the brackets make a difference in mySql)

Query not resulting correct records

I have this query:
SELECT id, name FROM users
WHERE ((id = 1) OR (5 <= 5))
This should result all records as 5 = 5, but it's not. It's only resulting records where the id = 1.
What am I doing wrong?
EDIT:
This is the full query:
SELECT project_id, project_name, project_description, project_active,
users.user_firstname, users.user_lastname FROM projects
INNER JOIN users ON projects.user_id = users.user_id
WHERE (projects.user_id = 1 || 3 <= 3)
EDIT:
Found it =/
Something was wrong with the join; user_id didn't exist anymore for some reason.
Try:
EXPLAIN EXTENDED SELECT id, name FROM users where id=1 or 5<=5;
SHOW WARNINGS;
u will find mysql executes the query is:
SELECT id,name FROM users where 1
just means (id=1 or 5<=5) is same as 1
So do you want all records smaller or equal 5?
if so its only
SELECT id, name FROM users
WHERE id <= 5
Beside that
(5 <= 5)
is "5" a table row like id?
Do this
$q = ("SELECT id, name FROM users WHERE id = 1 || 5 <= 5");
This is how I do it.

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