mysql related query - mysql

I need to write a query where I need to retrieve the data from a table.
Table
===================================
ID | userID | Status | date |
===================================
1 3333 Queued xxxx
2 4444 Queued yyyy
3 5555 Finished zzzzz
5 6666 Queued iiiii
6 7777 Queued kkkkk
Now i want to retrieve the row only if the status="Queued" and rows with status= "Queued" are more than 2 and the row with most recent ID . ie i want the answer to be ID = 6
I tried with the below query
select * from t1 where status = "Queued" GROUP BY status HAVING count(status) > 2 ORDER BY ID DESC limit 1

You could use a subquery for that. The problem is that the ordering is done before the grouping. Something like this should work:
select * from t1 where ID = (select max(id) from t1 where status = "Queued" group by status having count(status) > 2)

This variant is also possible -
SELECT * FROM (
SELECT * FROM t1 WHERE status = 'Queued' ORDER BY ID DESC) t
GROUP BY status HAVING count(status) > 2;

The following query should solve it:
select * from t1
where id = (select max(id) from t1 where Status = 'Queued' group by Status having count(1)>2);

Related

get the total count but exclude certain condition

Hello I had this table:
id | user_id | status
1 | 34 | x
2 | 35 | x
3 | 42 | x
4 | 42 | y
My goal is to count the data with X status except if the user has a another data with Y status, it will exclude in the count. So instead of 3, it will only count 2 since the 3rd row has another data which is the 4th row with y status.
SELECT * FROM logs
AND user_id NOT IN (SELECT user_id FROM logs WHERE status = 'y')
GROUP BY user_id;
We can try the following aggregation approach:
SELECT COUNT(*) AS cnt
FROM
(
SELECT user_id
FROM logs
GROUP BY user_id
HAVING MIN(status) = MAX(status) AND
MIN(status) = 'x'
) t;
The above logic only counts a user having one or more records only having x status.
You can do it this way, I only modify a bit on your sql
SELECT COUNT(*) FROM (
SELECT u_id FROM tbl WHERE u_id NOT IN
(SELECT u_id FROM tbl WHERE status = 'y')
GROUP BY u_id
) as t
You can use inner join:
SELECT
count(t1.id) AS `cnt`
FROM
`test` AS t1,
`test` AS t2
WHERE
t2.`status`='y'
&& t1.`user_id` != t2.`user_id`;

How to get last record from single group

I have following type of table.I want to output of last record(most recent) of particular group.Please suggest My sql query.
Id Name random number
-------------------------
1 A 1233
2 A 1778
3 A 1221
4 B 1298
5 B 1289
6 C 1267
I want a last record of group A
e.g.
ID Name Random number
----------------------
3 A 1221
select id, name, random from table where Name='A' order by id desc limit 1
Here is query :
select * from tbl where id IN (select max(id) from tbl group by name);
And here is fiddle: http://sqlfiddle.com/#!2/01d69/8
SELECT * From Table1 Where [Id] in (
SELECT Max([Id]) as [maxId] From Table1 Where [Name] = 'A')
Fiddle

My SQL query to retrieve 4 columns based on unique records from two columns

Hi I'm trying to write a correct query for MySQL to retrieve values from 4 columns (from, to, content, date or all if that's easier) based on 2 columns being unique in the same table. The idea is to retrieve a list of only last messages sent and received by a user X
TABLE
msg_id|msg_from|msg_to|msg_new|msg_content|date
1 user1 sw1 1 message1 2014-02-06
2 user1 sw1 1 message2 2014-02-06
3 user1 sw3 0 message3 2014-02-06
4 user1 sw5 0 message4 2014-02-06
5 sw2 sm2 1 message5 0000-00-00
6 sw2 sm4 1 message6 2014-02-20
7 sw1 user1 1 message7 2014-02-20
8 user1 sw5 1 message8 2014-02-20
My last attempt :
SELECT t1.* FROM (SELECT MAX(msg_id) AS nr, msg_from, msg_to
FROM com_msg GROUP BY msg_from) AS t2
INNER JOIN com_msg t1 ON t1.msg_from=t2.msg_from AND t1.msg_id=t2.nr
WHERE t1.msg_to='sw1' OR t1.msg_from='sw1'
which returns :
2| user1|sw1 |1|message2|2014-02-06
7| sw1 |user1|1|message7|2014-02-20
but should only return :
7| sw1 |user1|1|message7|2014-02-20
If I understant your question correctly, this query should return what you need:
SELECT com_msg.*
FROM com_msg INNER JOIN (SELECT MAX(msg_id) max_id
FROM com_msg
WHERE 'sw1' IN (msg_from, msg_to)
GROUP BY
CASE WHEN msg_from!='sw1' THEN msg_from
ELSE msg_to END) m
ON com_msg.msg_id = m.max_id
IDs needs to be ordered, otherwise you should use MAX(date)
Please see fiddle here.
Basically, you need to wrap this with another query, because your where clause is showing you records where either the to or the from equal the user. I'm not a MySQL guru, but you should be able to do something like this:
select top 1 *
FROM (
SELECT t1.* FROM (
SELECT MAX(msg_id) AS nr, msg_from, msg_to
FROM com_msg
GROUP BY msg_from
) AS t2
INNER JOIN com_msg t1 ON t1.msg_from=t2.msg_from AND t1.msg_id=t2.nr
WHERE t1.msg_to='sw1' OR t1.msg_from='sw1'
)
ORDER BY date DESC
This will return the most recent entry from your results based on the date.
If you are looking for just a single record returned of the last email like your example shows, this should do it...
Select TOP 1 msg_from, msg_to, msg_content, date
From com_msg
Where msg_from='sw1' OR msg_to='sw1'
ORDER BY msg_id DESC

Select Query to get last 3 calls and mails

I have 2 tables. One of tables has all mails from users and other table has all calls from users.
Table 1
call_id, | call_date | user_id
1 | 10/01/12| 3
2 | 9/01/12 | 3
Table 2
mail_id, | mail_date | user_id
1 | 8/01/12 | 3
2 7/01/12 | 3
I need to get last last 3 calls and mails :
10/01/12 - call
9/01/12 - call
8/01/12 - mail
Assuming MySQL, and for just one User_ID...
SELECT
*
FROM
(
SELECT 'call' AS type, id, call_date AS event_date, user_id FROM table_1
UNION ALL
SELECT 'mail' AS type, id, mail_date AS event_date, user_id FROM table_2
)
data
WHERE
user_id = 3
ORDER BY
event_date DESC
LIMIT
3
EDIT: Ooops, forgot to specify DESC in the ORDER BY, sorry.
Declare #userID int;
SET #userID=3;
select call_id FROM table_1
where user_id=#userID
order by call_date desc limit 2
UNION ALL
select mail_id FROM table_2
where user_id=#userID
order by mail_date desc limit 1

How to achieve next and previous row in a query

I have a table like this in MYSQL:
SELECT * FROM test_table
id u_id name date
1 101 name2 2012-05-14
2 305 name3 2012-05-11
3 506 name4 2012-05-05
4 207 name5 2012-05-12
5 108 name6 2012-05-03
SELECT id,u_id from test_table order by date;
id u_id
5 108
3 506
2 305
4 207
1 101
I have a application where where these things are displayed
on clicking on any u_id it takes me to a different page which displyed details stuff
Now I want to write a query which willl give me the next record
How do I achive the next record from here like
when I say u_id>305 it shoud give me 207?
and u_id<305 it should give me 506
I think this is what you are looking for:
SELECT id, u_id
FROM test_table
WHERE uid > 305
ORDER BY date ASC
LIMIT 1;
SELECT id, u_id
FROM test_table
WHERE uid < 305
ORDER BY date DESC
LIMIT 1;
Given the u_id is 305, to get the next record by date:
SELECT id,u_id
FROM test_table a
WHERE a.date > (SELECT date FROM test_table b WHERE b.u_id = 305)
ORDER BY a.date
LIMIT 1;
And to get the previous record by date:
SELECT id,u_id
FROM test_table a
WHERE a.date < (SELECT date FROM test_table b WHERE b.u_id = 305)
ORDER BY a.date DESC
LIMIT 1;
try this:
select id,u_id from
(SELECT id,u_id,#rownum:= #rownum+1 AS Sno
from test_table , (SELECT #rownum:=0) r;
order by date)a
where Sno=<#ID-1/+1>
lets say if your current Sno=5 then 4 will give the previous record and 6 will give the next record