MySQL, combining DISTINCT and JOIN - php

I have a table of users, called ..wait for it... "users".. and then another table which records users' activity called ...you'll never guess... "activity"..
I have an HTML table which shows the users in the users table, but I want to order the table by the users' last activity.
Here's my query.
SELECT *
FROM `users`
JOIN `activity`
ON `activity`.`user_id` = `users`.`id`
ORDER BY `activity`.`timestamp`
LIMIT 25
The problem here is that it shows multiple rows for each user since there are multiple records for each user in the activity table.
How can I alter the query to only show one record for each user and order them by the last activity in the activity table.?
I did experiment with using the "DISTINCT" keyword but no luck :/

"one record for each user and order them by the last activity in the activity table.?"
Couly try this? Assuming you need both user info and activity info.
SELECT users.*, a.*
FROM users INNER JOIN (
SELECT user_id, MAX(timestamp) max_timestamp
FROM activity
GROUP BY user_id
) x ON users.user_id = x.user_id
INNER JOIN activity a ON x.user_id = a.user_id AND a.timestamp = x.max_timestamp
ORDER BY a.timestamp;
inner sub-query finds max_timestamp per user_id and outer JOIN finds activity has max_timestamp and user_id

This is not SQL solution, but what I would do is keep lastActivity column in Users table and update it when needed. Then sorting, filtering by this column would be very easy and efficient.

Related

How to combine these 2 queries into 1 and avoid extra code

I have 2 tables in database, table users lists all users and their inviters (referrers) , table donations lists all the donations
The only connection between 2 tables is the user_id in table donations which is the id (Primary AI) in table users
What i want to do is get count of all users in table users which have ref='$referrer' and then see how many of them have donated and they are in donations table (each user can donate multiple times so it shouldn't count 2 donations as 2 users)
What i have tried:
first i get each ref of that inviter
SELECT id FROM users WHERE ref='$referrer'
then i put it in a while() loop and for each one of them i check if they have a donation
SELECT * FROM donations WHERE user_id='$id'
if they are found that counts as 1++
Issue
issue is if a user invited +500 people, then i send 500 queries in a loop with PHP, which takes time and resource
What is needed
I need a single Query with sub-Query to take only referrer id (ref='$referer') and give me count of all user X's referrals (every user with ref='55' in table users for example) which also have at least one donation in donations table
something like:
SELECT COUNT(*) FROM donations WHERE user_id = (SELECT id as user_id FROM users WHERE ref='$referer')
Can any one please help me with that
SELECT COUNT(*) FROM donations d INNER JOIN users u ON d.user_id=u.id WHERE u.ref='$referrer' GROUP BY d.user_id
Try this:
SELECT users.id, COUNT(*) `donations_count`
FROM users
INNER JOIN donations ON user.id = donations.user_id
WHERE users.ref='$referrer'
GROUP BY users.user_id

Inner, outer or full join on three tables in MySQL database on linux with apache

I want to have some help creating my query to get information from three different tables sharing information in common.
My first table is:
auctions
id title description user_id(who posted it)
My second table is:
bids
id user_id bid auction_id owner_id
My third table is:
users
id username X XX XXX XXXX
...and my SQL is as follows however it's not returning any results:
SELECT auction_bids.user_id AS applicant, auction_bids.*, auctions.title FROM auction_bids, auctions
WHERE auctions.user_id=".$_SESSION['userid']."
INNER JOIN users ON auction_bids.user_id = users.id
WHERE auction_bids.owner_id = ".$_SESSION['userid']."
What I need is to capture the auction's title, username who bidded on the auction and the bid. the auction has to have a bid and posted by the user who owns the $_SESSION['userid'].
Any help is appreciated.
You have two different 'where' statements, which may just need combining;
SELECT auction_bids.user_id AS applicant, auction_bids.*, auctions.title FROM auction_bids, auctions
INNER JOIN users ON auction_bids.user_id = users.id
WHERE auction_bids.owner_id = ".$_SESSION['userid']." AND auctions.user_id=".$_SESSION['userid']."
However, I'm not sure this is really what you want, as it will return only records where the specific user both 'owns' the item AND has bidded on it (both based on the userid session), rather than displaying all records from different people who have bidded on an item 'owned' by the user.
Something like: ?
SELECT auction_bids.user_id AS applicant, auction_bids.*, auctions.title FROM auction_bids, auctions
INNER JOIN users ON auction_bids.user_id = users.id,
WHERE auction.owner_id = ".$_SESSION['userid']."
Hope this points you in the right direction!
you have 2 where clauses, that is incorrect. I have revised your query based on your requirements.
SELECT auction_bids.user_id AS applicant, auction_bids.*, auctions.title
FROM auction_bids, auctions
INNER JOIN users ON auction_bids.owner_id = users.id
WHERE auction_bids.owner_id = ".$_SESSION['userid']."
AND auctions.user_id=auctions_bids.owner_id

PHP MySQL Active Record criteria sum

I have two tables, users and visits. I want to select all users who have 'active' in the visits table's status field, with a count of all visit records regardless of active/inactive status.
This query would only give me a count of 'active' visit records
SELECT
users.user_id,
COUNT(visits.id)
FROM users u
JOIN visits v ON v.user_id=u.user_id
WHERE visits.status='active'
I was thinking of a subquery, or a php loop but worried about performance if the users table grows. If subquery's the best solution please post the active record code.
A sub-query will be more efficient than looping in the code. I'd suggest this query:
select u.user_id, ucount
from users u
join (
select user_id, COUNT(id) as ucount
from visits
group by user_id
) all
ON u.user_id = all.user_id
join visits v
on v.user_id=u.user_id
where v.status='active'
And if you need only user_id and no users.* field, then you don't have to join to users table (inspired by answer from arunmoezhi):
select user_id,count(*) as visit_count
from visits v
join (
select user_id from visits
where status ='active'
) act
on v.user_id=act.user_id
group by v.user_id;
Edited for formatting.
select user_id,count(*) as visit_count
from visits
where user_id in(
select user_id from visits
where status ='active'
)
group by user_id;

Mysql select oldest record for each user

I'm trying to create a list in PHP of the oldest entries for each user in the database.
SELECT *,
MIN(`entries`.`entry_date`)
AS entry_date
FROM (`entries`)
JOIN `user_profiles`
ON `user_profiles`.`user_id` = `entries`.`user_id`
WHERE `status` = 1
GROUP BY `entries`.`user_id`
I'm using the query to retrieve from the entries table the oldest dated entry using MIN()and joining with table user_profiles for other data. The query should select the oldest entry for each user. It seems to work but it retrieves the wrong entry_date field on some entries when I echo them. Please help, I can't spot what I'm doing wrong..
You need to use a subquery to obtain the (user_id, entry_date) pairs for each user, then join that with a query that selects the records of interest:
SELECT *
FROM entries
NATURAL JOIN (
SELECT user_id, MIN(entry_date) AS entry_date
FROM entries
GROUP BY user_id
) AS tmin
JOIN user_profiles USING (user_id)
WHERE status = 1
Have you tried approaching the problem from the user_profiles table instead of the entries table? If a user has no entries, they will not appear in the above query.
This may help, but I'm not sure if it's the full solution:
SELECT *, MIN(entries.entry_date) as entry_date
FROM user_profiles LEFT JOIN entries USING (user_id)
WHERE status = 1
GROUP BY user_profiles.user_id
Also, you're renaming the MIN(entires.entry_date) as entry_date... but you already have a column named entry_date. Try renaming the derived columns to something unique like "min_entry_date"?

MYSQL SELECT To fetch rows from two tables with or without a foreign key

I am looking for some help with a MYSQL query. I have two tables, one contains a list of tickets and the other is a list of members.
Table Tickets:
ticket_id,
member_id
Table Members:
member_id
A member can but doesn't have to be assigned to a ticket. What I would like to do is select all the tickets and then if the member_id field is set in the tickets table fetch the member information as well.
One approach is to do a SELECT * FROM Tickets and then loop through in PHP and check if the member_id field is set. If set then do another query on the members table to fetch the corresponding information. The only problem with this is that it would be a large number of queries.
Is there any way to fetch all the results in one join query?
Thanks
Select *
from Tickets
Left Join Members On tickets.member_id = members.member_id
select * from tickets left outer join members on tickets.member_id = members.ticket_id
SELECT t.ticket_id, t.member_id FROM tikcets t LEFT JOIN members m ON t.member_id = m.member_id
This will give you all the tickets whether they have been assigned to a member or not.
You should add to the query the additional fields that you want to fetch.
Try this:
SELECT t.ticket_id, m.member_id
FROM tickets AS t LEFT OUTER JOIN members AS m
ON t.member_id = m.member_id
The LEFT OUTER JOIN will cause all results from tickets to be returned, and any match from members, not disqualifying the ticket records, so this could do the trick.

Categories