I am trying to change 'from_user' with a parameter from the other table and it doesn't work but when I am using the same table it works like a charm:
SELECT from_user, message_contents, message_read, to_user, date
FROM table1
WHERE date IN (
SELECT MAX( date )
FROM table1
WHERE to_user = 1 GROUP BY from_user
)
ORDER BY from_user ASC , date DESC
but this one just show one record but not all latest ones:
SELECT table2.`display_name`, message_contents, message_read, to_user, date
FROM table1, table2
WHERE table1.`from_user` = table2.`ID`
AND date IN ( SELECT MAX( date )
FROM table1
WHERE to_user = 1 GROUP BY from_user
)
ORDER BY from_user ASC , date DESC
Can anybody help to change 'from_user' with table2.display_name parameter but to get all recent records from mySQL?
You are joining two tables on table1.from_user = table2.id
So, if you don't want that table two to affect the number of rows than you can make a query like this:
SELECT
table1.from_user,
table2.`display_name`,
message_contents,
message_read,
to_user,
date
FROM table1
LEFT JOIN table2 ON table1.`from_user` = table2.`ID`
WHERE
date IN (SELECT MAX(date) FROM table1 WHERE to_user = 1 GROUP BY from_user)
ORDER BY from_user ASC , date DESC
I added also table1.from_user on the select clause which will help you see the from users which don't have a display name.
Related
I have a table in my database (versions: MariaDB 10.3.17, MySQL 5.7) as follows:
id name timestamp
-----------------------------
154875 AXC 154875869
362574 RTB 154875800
962548 MNV 154875969
365847 XRT 154875123
...
what I need:
sort the rows on timestamp descending
then return 24 rows after (below) where id=something
for example for id=962548, the first 3 rows of the expected output will be:
id name timestamp
-----------------------------
154875 AXC 154875869
362574 RTB 154875800
365847 XRT 154875123
how to implement it in MySQL?
Join the query that returns the row with id = something to the table under your conditions:
select t.*
from tablename t
inner join (select * from tablename where id = 365847) c
on t.timestamp < c.timestamp or (t.timestamp = c.timestamp and t.id < c.id)
order by t.timestamp desc, t.id desc
limit 24
but I'm not sure what you mean by below, so maybe you want the opposite order:
select t.*
from tablename t
inner join (select * from tablename where id = 365847) c
on t.timestamp > c.timestamp or (t.timestamp = c.timestamp and t.id > c.id)
order by t.timestamp desc, t.id desc
limit 24
You need to select elements that have the timestamp value greater than your id timestamp, using a query like this:
SELECT *
FROM table
WHERE timestamp>(select timestamp
from table
where id = 'current_id')
ORDER BY timestamp LIMIT 24;
I'd query it something like that:
SELECT * FROM tab
WHERE timestamp >= (SELECT timestamp FROM tab WHERE id = 154875)
AND id <> 154875
ORDER BY timestamp DESC, id DESC
LIMIT 2
I have a table CONTACT with a field opt_out.
The field opt_out may have values 'Y', 'N' and NULL.
I have a table CONTACT_AUDIT with fields
date
contact_id
field_name
value_before
value_after
When I add a new contact, a new line is added in the CONTACT table, nothing the CONTACT_AUDIT table.
When I edit a contact, for example if I change the opt_out field value from NULL to 'Y', the opt_out field value in CONTACT table is changed and a new line is added to CONTACT_AUDIT table with values
date=NOW()
contact_id=<my contact's id>
field_name='opt_out'
value_before=NULL
value_after='Y'
I need to know the contacts who had opt_out='Y' at a given date.
I tried this :
SELECT count(*) AS nb
FROM contacts c
WHERE
( -- contact is optout now and has never been modified before
c.optout = 'Y'
AND c.id NOT IN (SELECT DISTINCT contact_id FROM contacts_audit WHERE field_name = 'optout')
)
OR ( -- we consider contacts where the last row before date in contacts_audit is optout = 'Y'
c.id IN (
SELECT ca.contact_id
FROM contacts_audit ca
WHERE date_created BETWEEN '2014-07-24' AND DATE_ADD( '2014-07-24', INTERVAL 1 DAY )
AND field_name = 'optout'
ORDER BY date_created
LIMIT 1
)
)
But mysql does not support LIMIT in subquery.
So I tried with HAVING :
SELECT count(*) AS nb
FROM contacts c
WHERE
( -- contact is optout now and has never been modified before
c.optout = 'Y'
AND c.id NOT IN (SELECT DISTINCT contact_id FROM contacts_audit WHERE field_name = 'optout')
)
OR ( -- we consider contacts where the last row before date in contacts_audit is optout = 'Y'
c.id IN (
SELECT ca.contact_id
FROM contacts_audit ca
WHERE date_created BETWEEN '2014-07-24' AND DATE_ADD( '2014-07-24', INTERVAL 1 DAY )
AND field_name = 'optout'
HAVING MAX(date_created)
)
)
The query runs, but now, I don't know how to know if the value corresponding to the subquery value is 'Y' or 'N'. If I add a WHERE clause to check only for 'Y' values, 'N' values will be filtred and I will not be able to know if the last value at date was 'Y' or 'N'...
Thank you for your help
If i understand your problem correctly you may want to use a union. I dont have mysql to test it right now but the code could be something like this. tell me if this helped
select c.id, c.optout
where c.optout = 'Y'
AND c.id NOT IN (SELECT DISTINCT contact_id FROM contacts_audit WHERE field_name = 'optout')
UNION
select c.id, c.optout where c.id IN (
SELECT ca.contact_id
FROM contacts_audit ca
WHERE date_created BETWEEN '2014-07-24' AND DATE_ADD( '2014-07-24', INTERVAL 1 DAY )
AND field_name = 'optout'
HAVING MAX(date_created)
)
When I tried:
select *
from some_table
group by table_id
order by timestamp desc;
I am gettings rows which have least timestamp values for that particular table_id(which I use for grouping)
How can I get the rows which have highest timestamp values for that particular table_id.
I also tried:
select *
from some_table
group by table_id
having max(timestamp)
order by timestamp desc;
which gives the same result as in the 1st case.
Thank You
select *
from your_table t
inner join
(
select table_id, max(created_timestamp) as mts
from your_table
group by table_id
) x on x.table_id = t.table_id
and x.mts = t.created_timestamp
In MySQL you can do
select *, max(created_timestamp) as mts
from your_table
group by table_id
but that will not make sure you get the corresponding data to your max(created_timestamp) but only to your table_id
SELECT * FROM (SELECT * FROM some_table ORDER BY timestamp) t1 GROUP BY t1.id
I have a query
select user_id,sum(hours),date, task_id from table where used_id = 'x' and date >='' and date<= '' group by user_id, date, task_id with roll up
The query works fine. But I also need to find a second sum(hours) where the group by order is changed.
select user_id,sum(hours),date, task_id from table where used_id = 'x' group by user_id,task_id
(The actual where condition is much longer.)
Is it possible to get both the sum in a single query since the where condition almost the same?
SELECT * FROM (
SELECT 1 AS list_id
, user_id
, sum(hours) AS total_hours
, `date`
, task_id
FROM table WHERE used_id = 'x' AND `date` BETWEEN #thisdate AND #thatdate
GROUP BY user_id, `date`, task_id /*WITH ROLLUP*/
UNION ALL
SELECT 2 AS list_id
, user_id
, sum(hours) AS total_hours
, `date`
, task_id
FROM table
WHERE used_id = 'x'
GROUP BY user_id,task_id WITH ROLLUP ) q
/*ORDER BY q.list_id, q.user_id, q.`date`, q.task_id*/
Depending on your needs, you should only need one with rollup, or two.
I have a table whose structure is as follows:
id int
userid int
status enum ('pending','approved')
dop datetime
Data is as:
id userid status dop
1 24 pending 2011-02-14 06:41:32
2 24 pending 2011-02-15 23:02:45
When I fire the following query:
SELECT count( userid )
FROM t1
WHERE STATUS = 'pending'
GROUP BY userid
It's giving me count as '2', which is wrong, can anyone tell me what's wrong here? and how to get real count as 1
The group by statement is executed after the count. Use this instead:
SELECT count( DISTINCT userid )
FROM t1
WHERE STATUS = 'pending'
Do you want to count the number of user with status pending then?
SELECT count(userid)
FROM t1
WHERE STATUS = 'pending'
GROUP BY status, userid
Try to add the userid in the select clause :
SELECT userid, count( userid )
FROM t1
WHERE STATUS = 'pending'
GROUP BY userid
Maybe adding DISTINCT() on userid?
SELECT count( DISTINCT userid )
FROM t1
WHERE STATUS = 'pending'
GROUP BY userid
You sould use the COUNT(DISTINCT()) construction, it allow you to count the diferent values not NULL (docu)
Try this sentence:
SELECT count( DISTINCT( userid ) )
FROM t1
WHERE STATUS = 'pending'
GROUP BY userid
HTH!