looking for tricky sql query solution - mysql

i'm having the following database structure (for messaging):
id from_userid to_userid time_stamp message
let's say i'm user with id 1 and i want to get a list of ALL user_ids i've been interacting with, sorted by timestamp - any idea how to do it?
thanks

Something like this, perhaps?
SELECT *
FROM (
SELECT from_id AS id, time_stamp
FROM <table>
WHERE to_id=<user id>
UNION
SELECT to_id AS id, time_stamp
FROM <table>
WHERE from_id=<user id>
) AS t
ORDER BY time_stamp

SELECT *
FROM your_table
WHERE from_userid = 1 OR to_userid = 1
ORDER by time_stamp

I would do it like this:
select all values + timestamps where "me" is from_userid
select all values + timestamps where "me" is to_userid
in both selects assign the same name to the "other" user id
join the result sets using UNION ALL
then order the result by the timestamp column
group by user id and min(timestamp)
In sql it would be something like this:
select rel_user, min(time_stamp) as first_contact from
(
select time_stamp, to_userid as rel_user where from_userid=my_ID
union all
select time_stamp, from_userid as rel_user where to_userid=my_ID
)
group by rel_user
order by min(time_stamp)

Since all of the other ways use more than one SELECT here's one using CASE
SELECT CASE
WHEN to_userid=1 THEN from_userid
ELSE to_userid
FROM table WHERE to_userid=1 OR from_userid=1 ORDER BY time_stamp

Related

Add the result of SELECT query in another SELECT query

This is the result of a UNION of two SELECT
SELECT count(*) FROM
((SELECT session_id_current_user from test.tws_analytics
WHERE (add_date BETWEEN '2022-05-15' AND '2022-05-15') AND ((pathURL='vues/login.php' AND name_current_user='') OR (pathURL='' AND searchURL='?job=forgotten' AND name_current_user=''))
AND session_id_current_user NOT IN
(SELECT session_id_current_user from test.tws_analytics
WHERE (pathURL <> 'vues/login.php' AND searchURL <> '?job=forgotten') AND add_date BETWEEN '2022-05-15' AND '2022-05-15' order by session_id_current_user)
order by session_id_current_user)
UNION
(SELECT name_current_user from test.tws_analytics where add_date BETWEEN '2022-05-15' AND '2022-05-15' AND name_current_user IS NOT NULL AND name_current_user <> ''))
AS tem
The result is 11.
What I want to do is to select this result with other columns like this :
SELECT count(session),count(name), [AND tem.count(*)] FROM ....
This is the general idea, though i didn't know how to implement it.
a simplified general answer would be
select * from (select count(*) numsessions from sessions), (select count(*) numusers from users)
this will give 2 different counts, i didn't include the logics that you provided, but that will need to be done inside the 2 subqueries.

MySQL aggregate sum of count

I have a simple group by query:
SELECT timestamp, COUNT(users)
FROM my_table
GROUP BY users
How do I add a sum_each_day column that will sum the users count of each row and will aggregate it forward to the next row and so on
The output should be like this:
timestamp | users | sum_each_day
2015-11-27 1 1
2015-11-28 5 6
2015-11-29 3 9
2015-11-30 7 16
Thanks in advance
You could use a sub-query, like this:
SELECT timestamp,
num_users,
(SELECT COUNT(users)
FROM my_table
WHERE timestamp <= main.timestamp) sum_users
FROM (
SELECT timestamp,
COUNT(users) num_users
FROM my_table
GROUP BY timestamp
) main
If you really need this in mysql it'll cost some performance but i believe a sub query with a count will solve it:
SELECT t1.timestamp, count (), select count () from my_table t2 where t2.timestamp <= t1.timestamp From my_table t1 Group by users
If you display this data through a scripting language like PHP it would be easier to keep a counter and display the aggregate per row.
I would do this using variable:
SET #total := 0;
SELECT timestamp, DayCount, (#total := #total + DayCount) AS Total
FROM
(SELECT timestamp, COUNT(users) AS DayCount
FROM my_table
GROUP BY timestamp) AS t1
Fiddler: I am not using your table structure here, but you can get idea
If I understand correclty, this will work:
set #c=0;
SELECT `timestamp`,sum(`users`),(select #c:=#c+sum(`users`))
FROM `my_table`
group by `timestamp`;

Change parameter in MySQL request SELECT

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.

mysql 2 set of sum using groupby rollup

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.

wrong count in query

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!