MySql database selecting count(column) using inner joins - mysql

I have three tables
USER : idUser, Username
USERLOCATION : idUser, idLocation
SESSION : idUser, idSession
What I want to find is all the users that are from a particular location and count how many sessions they have had. I'm nearly there with this SQL
SELECT u.idUser, u.Username, s.idSession
FROM rempad.User u
INNER JOIN rempad.UserLocation l ON u.idUser = l.idUser
INNER JOIN rempad.Session s ON u.idUser = s.idUser
WHERE l.idLocation = 12
This returns all the users belonging to a particular location and all the session ids. Where I am stuck is that I really want to be able able to count the the sessions for each user.
I've tried...
SELECT u.idUser, u.Username, COUNT(s.idSession) as SessionCount
but this returns only a single row and counts all the sessions in the session table rather than counting the sessions that belong to each individual user at that location.
Do I need to do a nested SELECT statement? I'm not really sure how to go about writing the query.
Any help much appreciated.
L

Try this:-
SELECT u.idUser, u.Username, count(s.idSession) as x
FROM rempad.User u
INNER JOIN rempad.UserLocation l ON u.idUser = l.idUser
INNER JOIN rempad.Session s ON u.idUser = s.idUser
WHERE l.idLocation = 12
GROUP BY u.iduser,
u.username

I believe it would be better to use Group by along with the above
SELECT u.iduser,
u.username,
Count(s.idsession) AS x
FROM USER u
INNER JOIN userlocation l
ON u.iduser = l.iduser
INNER JOIN session s
ON u.iduser = s.iduser
WHERE l.idlocation = 12
GROUP BY u.iduser,
u.username

Related

Sort the table by COUNT after displaying values from multiple tables

My goal is: display how often is specific ID repeated as the topic_poster in one table, phpbb_topics, but only if the proper forum_id condition is also met, then also display the corresponding username from another table, phpbb_users.
I have successfully extracted the count of how often is one specific userID occuring as the topic_poster in table phpbb_topics, like that:
SELECT topic_poster, COUNT(topic_poster)
FROM phpbb_topics WHERE forum_id = 156
GROUP BY topic_poster
Thanks to another question on StackOverflow I now also know how to get data from another table to get the username corresponding to the specific userID, like that:
SELECT t.topic_poster, u.user_id, u.username
FROM phpbb_topics t
LEFT JOIN phpbb_users u ON u.user_id = t.topic_poster
I also managed to finally mix the two to get what I want:
SELECT t.topic_poster, COUNT(t.topic_poster), u.user_id, u.username
FROM phpbb_topics t
LEFT JOIN phpbb_users u ON u.user_id = t.topic_poster WHERE t.forum_id = 156
GROUP BY t.topic_poster
However, I do not know how to properly sort in descending or ascending order based on the counter. phpmyAdmin won't let me just click on the column's name to sort by it, and any queries i write with GROUP BY or ORDER BY are reporting errors.
Update:
after putting this in:
SELECT t.topic_poster, COUNT(t.topic_poster), u.user_id, u.username
FROM phpbb_topics t
LEFT JOIN phpbb_users u ON u.user_id = t.topic_poster WHERE t.forum_id = 156
ORDER BY COUNT(topic_poster)
the results display only one row:
topic_poster |COUNT(t.topic_poster) | user_id | username
6 | 254 6 | Opix
Same happens if I use this:
SELECT t.topic_poster, COUNT(t.topic_poster), u.user_id, u.username
FROM phpbb_topics t
LEFT JOIN phpbb_users u ON u.user_id = t.topic_poster WHERE t.forum_id = 156
ORDER BY COUNT(t.topic_poster)
Same happens if I use this:
SELECT t.topic_poster, COUNT(t.topic_poster), u.user_id, u.username
FROM phpbb_topics t
LEFT JOIN phpbb_users u ON u.user_id = t.topic_poster WHERE t.forum_id = 156
ORDER BY topic_poster
If I use this: SELECT t.topic_poster, COUNT(t.topic_poster), u.user_id, u.username FROM phpbb_topics t LEFT JOIN phpbb_users u ON u.user_id = t.topic_poster WHERE t.forum_id = 156 GROUP BY t.topic_poster I get all the results, but I can't sort by the counter.
mySQL extends the group by so you don't have to have one. However, it assumes all values for each column are the same; so it's free to pick what to put in from each column. However, if the values are different, what it picks (1 value) isn't representative of the entire set, so you must use group by when the values are different.
Put a different way: if t.forum_ID = 156 limited to a specific topic_poster, user_Id and username. you'd have no problem. But since t.forum_ID represents many different values in each of those columns, group by is needed or the engine will "somewhat" randomly select a value for each of them. The engine assumes all are the same.
Thus the downfall of the mySQL Group by extension. But, if all the non-aggregrated columns did have the same value... you get a performance gain by allowing the engine to just aggregate and 'pick' a value for each column.
Based on your response, you think you should be getting multiple rows. So that tells me the non-aggregated fields are different so add a group by...
SELECT t.topic_poster, COUNT(t.topic_poster), u.user_id, u.username
FROM phpbb_topics t
LEFT JOIN phpbb_users u ON u.user_id = t.topic_poster
WHERE t.forum_id = 156
GROUP BY t.topic_poster, u.user_id, u.username
ORDER BY COUNT(t.topic_poster)
You could have ties, so you may also want to order by poster or user name after the count...

How to select more rows based on column id of first select

I have 2 select statements. One returns 2 rows and the other must return more rows. I want to select all of the rows in one single query and not use a UNION because I will not be able to use the same column id with UNION.
My query is this
SELECT SUB.name FROM (SELECT U1.id ,U1.name, UOM.organization_id AS ORGID FROM #_users AS U1
JOIN #_user_organization_map AS UOM ON U1.id = UOM.user_id
JOIN #_rsdirectory_entries AS RSE ON UOM.organization_id = RSE.id
JOIN #_rsmembership_membership_subscribers AS RMS ON U1.id = RMS.user_id
WHERE RMS.membership_id = 66 AND UOM.organization_id = 301) AS SUB
JOIN #_users AS U ON SUB.id = U.id
JOIN #_user_organization_map AS UOM1 ON SUB.id = UOM1.user_id
JOIN #_rsdirectory_entries AS RSE1 ON UOM1.organization_id = RSE1.id
JOIN #_rsmembership_membership_subscribers AS RMS1 ON SUB.id = RMS1.user_id
WHERE UOM1.organization_id = SUB.ORGID;
What i'm trying to do is get all users belonging to a specific membership but not all users carry the membership_id value in their details in the database, only the CEO of the organization.
So, the nested SELECT should get the CEO's name to whom the subscription belongs (hence the membership_id) and then in the outer SELECT I want to get all of the employees under the same organization, by organization ID.
The result I get is the CEO's name twice but I should get the CEO's name and then all of the employees' names.
The subquery is only returning the CEO's information. The information about the employees is in the U table that you join with it.
But you can't join on U.id = SUB.id, because that just restricts U to the CEO's row. You want to get all the users in the same organization as the CEO.
I think this will do it. The last three joins get the organization ID of the CEO
SELECT U.name
FROM #_users AS U1
JOIN #_user_organization_map AS UOM1 ON1 U.id = UOM1.user_id
JOIN #_user_organization_map AS UOM ON UOM1.id = UOM.id
JOIN #_rsdirectory_entries AS RSE ON UOM.organization_id = RSE.id
JOIN #_rsmembership_membership_subscribers AS RMS ON U1.id = RMS.user_id
WHERE RMS.membership_id = 66 AND UOM.organization_id = 301

MYSQL: Using a join after and AND

the MYSQL query below combines a number of tables. However, as you can see, I would like to add a LEFT JOIN at the end on the receipt table. The query returns an error when I add the LEFT JOIN. Anybody know the best way to LEFT JOIN the receipt table to the rest of the query. Sorry if this is a newbie question. Thanks !!
SELECT user_name, expense_category, merchant_name, expense_cost, expense_date, expense_status, receipt_image, expense_comment
FROM users, expenses, merchants, receipts
WHERE ".$adminId." = expenses.admin_id
AND expenses.user_id = users.user_id
AND expenses.merchant_id = merchants.merchant_id
AND LEFT JOIN (receipts)
ON expenses.receipt_id = receipts.receipt_id
Here is a clean approach of doing it, note that I have added alias for the tables for better readability so you may use the alias name in the select statement to fetch the column from the proper table.
SELECT
u.user_name,
ex.expense_category,
mer.merchant_name,
ex.expense_cost,
ex.expense_date,
ex.expense_status,
re.receipt_image,
ex.expense_comment
FROM users u
JOIN expenses ex on ex.user_id = u.user_id
JOIN merchants mer on mer.merchant_id = ex.merchant_id
LEFT JOIN receipts re on re.receipt_id = ex.receipt_id
where
ex.admin_id = '$adminId'
Try this,
SELECT user_name, expense_category, merchant_name, expense_cost, expense_date, expense_status, receipt_image, expense_comment
FROM users, expenses, merchants, receipts
LEFT JOIN receipts ON expenses.receipt_id = receipts.receipt_id
WHERE ".$adminId." = expenses.admin_id
AND expenses.user_id = users.user_id
AND expenses.merchant_id = merchants.merchant_id
Use join clauses instead of where clause. I.e.
SELECT user_name, expense_category, merchant_name, expense_cost, expense_date, expense_status, receipt_image, expense_comment
FROM users
INNER JOIN expenses on users.user_id = expenses.expenses_id
INNER JOIN merchants on merchants.merchant_id = expenses.merchant_id
LEFT JOIN (receipts)
ON expenses.receipt_id = receipts.receipt_id
WHERE ".$adminId." = expenses.admin_id
Note that any columns from the receipts will be NULL in the select statement whenever there's no matching record.

Select Two Values Based Off Same Column

I am trying to select two usernames in one row of a query one would be called 'username' and the second one say 'username2'. This is the code I have atm. The users table uses a primary key of user_id.
SELECT
r.report_id,
r.poster_id,
r.reporter_id,
u.username,
(2nd username)
FROM reports r,
users u
WHERE r.report_id = :report_id
AND r.reporter_id = u.user_id
AND r.poster_id = u.user_id
you need to join the table user twice
SELECT
r.report_id,
r.poster_id,
r.reporter_id,
u.username AS ReporterName,
b.userName as PosterName
FROM
reports r
INNER JOIN users u
ON r.reporter_id=u.user_id
INNER JOIN users b
ON r.poster_id=b.user_id
WHERE
r.report_id=:report_id
Here is the code for MySQL
SELECT
r.report_id,
r.poster_id,
r.reporter_id,
u.username,
u.username username2,
FROM reports r,
users u
WHERE r.report_id = :report_id
AND r.reporter_id = u.user_id
AND r.poster_id = u.user_id

How to get good results from DB

i have a problem with sql query.
I need to get list of users. The problem is the left join i use.
this is my query
SELECT
u.*
FROM
users u LEFT JOIN game g on g.user_id = u.user_id
LEFT JOIN game_actions ga on ga.game_id = g.id
LEFT JOIN emails e on e.id = ga.email_id
WHERE
u.user_id = 0
AND u.is_contact_by_email = 1
AND email.type = 2
this query returns the same user more then once because of the join with other tables
i want this query to return each user just one time.
i'm using sql developer.
thanks in advanced.
Given that you're not using game, game_actions, or emails for any purpose (they're not filtering users, and you're not enriching the results with data from either of these tables), there's no need to join those tables at all:
SELECT
u.*
FROM users u
WHERE u.user_id = 0
AND u.is_contact_by_email = 1
You may group result by user_id and use aggregate functions to return other fields, for eaxmple -
SELECT u.user_id, GROUP_CONCAT(g.game_id) games FROM users u
LEFT JOIN game g
ON g.user_id = u.user_id
LEFT JOIN game_actions ga
ON ga.game_id = g.id
LEFT JOIN emails e
ON e.id = ga.email_id
WHERE
u.user_id = 0 AND u.is_contact_by_email = 1
GROUP BY
u.user_id
I suppose there are more games, actions, and emails for each user. How do you imagine the result table to look like? Because when you are selecting only from user table (SELECT u.*), then there is no point in joining others. If you need the other tables, use GROUP BY (u.user_id) to group rows by user.
Try to use keyword distinct with your query