MySQL Select Queries Explain - mysql

I have a question regarding a select mysql query. Lets say that we have 2 tables
users: [ id, username ]
logs [ id, user_id, action ]
I want to selecr all users from table users with the count(id) of table logs based on user_id
I tried to do the following:
SELECT t1.*,count(t2.`id`)
FROM `users` t1
LEFT JOIN `logs` t2
ON t1.id = t2.user_id;
But that only prints the users who have count logs > 0. I want to select all the users with the count of the logs.

SELECT t1.*,count(t2.`id`)
FROM `users` t1
LEFT JOIN `logs` t2
ON t1.id = t2.user_id
GROUP BY t1.id

Try this query :
SELECT *, (SELECT count(id) FROM `logs` WHERE `logs`.`id`=`id`) scount FROM `users`;
The count value you want will be in a field called scount.

Related

MySQL take rows and override ones without user_id

I have table like this one:
I would like to all rows, but if there is user_id 5 if this case, override other rows which have no user_id.
I tried both with MAX(user_id) and GROUP BY country_name, but it still returns, wrong results.
Final result I'm expecting:
Try this;)
select t1.*
from yourtable t1
inner join (
select max(user_id) as user_id, country_name from yourtable group by country_name
) t2 on t1.country_name = t2.country_name and t1.user_id = t2.user_id
This is just a solution based on your sample data. If you have a variety of user_id, it should be more different.
As of SQL Select only rows with Max Value on a Column you can easily get rows with max value on a column by using both MAX(column) and GROUP BY other_column in one statement.
But if you want to select other columns too, you have to this in a subquery like in the following example:
SELECT a.*
FROM YourTable a
INNER JOIN (
SELECT country_name, MAX(user_id) user_id
FROM YourTable
GROUP BY country_name
) b ON a.country_name = b.country_name AND a.user_id = b.user_id

Mysql Join 3 Tables in One Query with sorted Result

I have 3 tables and want to join all in one query to show latest 10 entries by datetime.
t1: id, username
t2: id, id_t1, med_id, ga_id, au_id, re_id, text, datetime
t3: id, id_t1, pro_id, au_id, re_id, text, datetime
First I saw it would be easy with simple left join and where id, but i got double results. Then i tried inner and outer join, also group by, but the result was bad.
So my question is how can i join all without double results of the last 10 of t2 and t3?
Hard to tell what exactly you are trying to acheive, but here is a clue how it could be complemented.
SELECT TOP 10 DISTINCT T1.*
FROM T1
INNER JOIN T2 ON T1.id = T2.id_t1
INNER JOIN T3 ON T1.id = T3.id_t1
ORDER BY (CASE WHEN T2.[DateTime] > T3.[DateTime] THEN
T2.[DateTime]
ELSE
T3.[DateTime]
END) DESC
If you need to select field from T2 and T3, GROUP BY on all T1 field with aggregate on field from t2 and t3 is an option. Otherwise, linked-subquery is the way to go.
As sgeddes commented already, it's hard to know what you need, without seeing some example data from your tables. It would really help to know what the relationship between the three tables is.
One question I have, in particular, is: how are t2 and t3 related, if at all? It looks like they might not be, as each of them has its own datetime column.
Perhaps the following could do the job, but we need some more info to know for sure:
(SELECT DISTINCT t1.*, t2.id, t2.au_id, t2.re_id, t2.text, t2.`datetime`, t2.med_id, t2.ga_id, NULL AS pro_id
FROM t1
INNER JOIN t2 ON t1.id = t2.id_t1)
UNION
(SELECT DISTINCT t1.*, t3.id, t3.au_id, t3.re_id, t3.text, t3.`datetime`, NULL AS med_id, NULL AS ga_id, t3.pro_id
FROM t1
INNER JOIN t3 ON t1.id = t3.id_t1)
ORDER BY datetime DESC
LIMIT 10
The following selects the username and the datetime for the last ten posts.
SELECT username, last_ten.`datetime` AS lastpost
FROM t1
INNER JOIN (
SELECT 't2' AS tab, id, `datetime`, t2.id_t1
FROM t2
UNION ALL
SELECT 't3' AS tab, id, `datetime`, t3.id_t1
FROM t3
ORDER BY datetime DESC
LIMIT 10
) AS last_ten ON t1.id = last_ten.id_t1

MySQL Select From Multiple Tables + Last row from somewhere else

Hello I have these 4 tables with the structure
Table: Users [ id, username, password, bouquet_id ]
Table: Bouquets [ id, bouquet_name, stream_ids = serialized array ]
Table: Streams [ id, channel_name ]
Table: activity [ id, user_id, stream_id ]
I want to select ALL users but with their info as well from other tables + THE LAST ROW from table activity per user
For example the following query:
SELECT t1.*,t2.`bouquet_name`
FROM `users` t1,`bouquets` t2
WHERE t1.`bouquet_id ` = t2.`id`
ORDER BY t1.id DESC
Takes the data from the first 2 tables and assigned the bouquet_id to its bouquet name.
Now i want to have in query the last ROW from activity table WITH it's stream name [based on stream_id]
The following query does the job i want[ PER USER]
SELECT t1.channel_name
FROM `streams` t1,`activity` t2
WHERE t2.user_id = **'%d'** AND t1.id = t2.stream_id
ORDER BY t2.id DESC
LIMIT 1
But its a kind slow since for every user in the table "users" i run 2 queries.
I want the 2 queries above to be embed together as one so that i will be able to select the data from the first two tables BUT WITH the last row from table activity based on user_id.
Hope you understand me
thank you
You should not depend on "last row" = "row with greatest id". Since MySQL provides the possibility to setup master-master replications, which then offers the possibility to assign auto_increment values in more or less arbitrary order, this assumption is not always true. An additional timestamp column would be better.
You can select the most recent activity per user for example with:
SELECT user_id, MAX(id) FROM activity GROUP BY user_id
You then have to join this into your query and join in the basic activity table to retrieve the data you actually want. You may want to replace your joins with left joins too, so you will always retrieve all users regardless if there exists rows in bouquets or activity:
SELECT t1.*, t2.`bouquet_name`, activity.*
FROM `users` t1
LEFT JOIN `bouquets` t2
ON t1.`bouquet_id ` = t2.`id`
LEFT JOIN (
SELECT user_id, MAX(id) AS maxid FROM activity GROUP BY user_id
) mostrecent
ON t1.user_id = mostrecent.user_id
LEFT JOIN activity
ON t1.user_id = activity.user_id AND activity.id = mostrecent.maxid
ORDER BY t1.id DESC
And then you can join in the stream data too like
SELECT t1.*, t2.`bouquet_name`, activity.stream_id, streams.channel_name
FROM `users` t1
LEFT JOIN `bouquets` t2
ON t1.`bouquet_id ` = t2.`id`
LEFT JOIN (
SELECT user_id, MAX(id) AS maxid FROM activity GROUP BY user_id
) mostrecent
ON t1.user_id = mostrecent.user_id
LEFT JOIN activity
ON t1.user_id = activity.user_id AND activity.id = mostrecent.maxid
LEFT JOIN streams
ON activity.stream_id = streams.id
ORDER BY t1.id DESC

MySQL Multiple Select Query

I want to create mysql request to the server I want to retrieve users from the table that as I do not have in friends list.
Here's how I'm trying to learn but I do not receive please help me
SELECT
t1.*, t2.*
FROM
users as t1,
friends as t2
WHERE
t2.user_id='1'
and t2.fr_id!=t1.id
ORDER BY RAND()
The query you want is something like:
SELECT t1.*, t2.*
FROM users t1 left outer join
friends t2
on t2.fr_id = t1.id and
t2.user_id = '1'
WHERE t2.user_id is null
ORDER BY RAND();
I'm not sure what the t2.user_id = 1 is doing. It is not needed if you are looking through the entire friends list.

MySQL merging two queries one with group by

I have two tables, one holds user info (id, name, etc) and another table that holds user tickets and ticket status (ticket_id, user_id, ticket_status, etc).
I want to produce a list of ALL the users for example: ( SELECT * FROM user_table )
And for each user I need a count of their tickets for example:
(SELECT t1.user_id, COUNT(*) FROM user_tickets t1 WHERE t1.ticket_status = 15 GROUP BY t1.ticket_status, t1.user_id )
I can do this query to achieve what I’m looking for but it takes 5sec. to run the query on 50000 tickets, while each query running separately only takes fraction of a second.
SELECT t1.user_id, COUNT(*)
FROM user_tickets t1
LEFT JOIN user_table t2 ON t1.user_id = t2.id
WHERE t2.group_id = 20 AND t1.status_id = 15
GROUP BY t1.status_id, user_id
Any idea how to write the query to get same performance as each separately?
An indexing where clause fixed the problem.