My first SQL query is:
SELECT username,COUNT(username) as total_active_users FROM users WHERE active = '1' GROUP BY referrer // $act_user
To count the active users for each referrer
The second sql query is:
SELECT COUNT(orders) as total_user_orders FROM users_orders GROUP BY $act_user['username'] // the username from the first query.
To count total number of orders for each user which i got from the first query
What I'm trying to do it using LEFT JOIN to only count active users who have 1 order at least
The problem is: I have 2 different GROUP BY the first one is "referrer" and the second is "username"
I'm trying to do something like :
SELECT u.username, COUNT(u.username) as total_active_users, COUNT(b.orders) as
total_user_orders FROM users u LEFT JOIN users_orders b on u.username = b.username
WHERE u.active = '1' AND total_user_orders >= '1' GROUP BY (u.referrer for u) and (b.username for b)
Any idea please?
You can do this instead:
SELECT
a.username,
COUNT(u.username) as total_active_users,
COUNT(b.orders) as total_user_orders
FROM
(
SELECT username FROM users_orders WHERE total_user_orders >= '1'
UNION ALL
SELECT username FROM users WHERE u.active = '1'
) AS a
LEFT JOIN users AS u ON a.username = u.username
LEFT JOIN users_orders AS b on u.username = b.username
GROUP BY a.username;
Assuming that user names are unique and that for a user to have at least one order means the same as for them to have at least one row in the users_orders table, you could do the following:
SELECT
u.referrer,
COUNT(DISTINCT u.username) AS usercount
FROM users u
INNER JOIN users_orders uo ON u.username = uo.username
WHERE u.active = 1
;
The join between users and users_orders acts as a filter (in addition to that on the active status). It may produce duplicate user names but COUNT(DISTINCT) will count unique entries only.
Related
I have a big data problem with MySQL.
I have:
a users table with 59033 rows, and
a user_notes table with 8753 rows.
But when I search which users have user note in some dates.
My query like this :
SELECT u.*, rep.name as rep_name FROM users as u
LEFT JOIN users as rep on rep.id = u.add_user
LEFT JOIN authorization on authorization.id = u.authorization
LEFT JOIN user_situation_list on user_situation_list.user_situation_id = u.user_situation
WHERE
EXISTS(
select * from user_notes
where user_notes.note_user_id = u.id AND user_notes.create_date
BETWEEN "2017-10-20" AND "2017-10-22"
)
ORDER BY u.lp_modify_date DESC, u.id DESC
Turn it around -- find the ids first; deal with the joins later.
SELECT u.*,
( SELECT rep.name
FROM users AS rep
WHERE rep.id = u.add_user ) AS rep_name
FROM (
SELECT DISTINCT note_user_id
FROM user_notes
WHERE create_date >= "2017-10-20"
AND create_date < "2017-10-20" + INTERVAL 3 DAY
) AS un
JOIN users AS u ON u.id = un.note_user_id
ORDER BY lp_modify_date DESC, id DESC
Notes
No GROUP BY needed;
2 tables seem to be unused; I removed them;
I changed the date range;
User notes needs INDEX(create_date, note_user_id);
Notice how I turned a LEFT JOIN into a subquery in the SELECT list.
If there can be multiple rep_names, then the original query is "wrong" in that the GROUP BY will pick a random name. My Answer can be 'fixed' by changing rep.name to one of these:
MAX(rep.name) -- deliver only one; arbitrarily the max
GROUP_CONCAT(rep.name) -- deliver a commalist of names
Rewriting your query to use a JOIN rather than an EXISTS check in the where should speed it up. If you then group the results by the user.id it should give you the same result:
SELECT u.*, rep.name as rep_name FROM users as u
LEFT JOIN users as rep on rep.id = u.add_user
LEFT JOIN authorization on authorization.id = u.authorization
LEFT JOIN user_situation_list on user_situation_list.user_situation_id = u.user_situation
JOIN user_notes AS un
ON un.note_user_id
AND un.create_date BETWEEN "2017-10-20" AND "2017-10-22"
GROUP BY u.id
ORDER BY u.lp_modify_date DESC, u.id DESC
I am working on social networking site.
I've three tables one is user table which is used to store user details, another table is follow table which is used for followers following list.
In this table I am storing user_id and follower_id.
Third table is user_friends in this I'm storing user_id and friend_userid.
I want to search the user from my friends list and follow list. For this i've written query like this:-
select f.follower_id,uf.friend_userid,u.user_id,u.first_name,u.last_name from tbl_user u
LEFT JOIN tbl_userfriends uf ON uf.friend_userid = u.user_id
LEFT JOIN tbl_follow f ON f.follower_id = u.user_id
where uf.friend_userid != '11'
AND u.first_name LIKE '%a%'
This query returning users only who are friends it is not returning the follow users.
Any help will be appreciated. Thanks in Advance.
You're joining tbl_follow on the Follower ID being equal to the User ID. I suspect that's probably not right.
If you don't already have one you'll need a user id key in the follower table to join on, then you can change your join to;
LEFT JOIN tbl_follow f ON f.userid = u.user_id
i've done this by using following query:-
select u.user_id,u.first_name,u.last_name from tbl_user u LEFT JOIN tbl_userfriends uf ON uf.friend_userid = u.user_id LEFT JOIN tbl_follow f1 ON f1.follower_id = u.user_id LEFT JOIN tbl_follow f2 ON f2.user_id = u.user_id where (uf.user_id = '11' OR f1.user_id = '11' OR f2.follower_id = '11') AND (u.first_name LIKE '%s%' OR u.last_name LIKE '%s%') AND u.status = '0' group by u.first_name
This query returning me all the users who are my followers, friends and to whom i am following.
I have three table group, user and belongs where belongs is relation between group and user.
Table group
group_id (pk)
group_name
Table user
user_id (pk)
user_name
Table belongs
user_id
group_id
I want to show a random groups that people in specified group are also in.
For example specified group is where group_id = 1, Of course, i can get people in this group by use
"SELECT user_id FROM user u JOIN belongs b ON u.user_id = b.user_id and b.group_id = '1'"
I have been trying, and now, i have no idea how to select group that these people are in too.
"SELECT g.* FROM group g WHERE ..."
Thanks in advance.
You can get all the groups by using an extra join:
SELECT DISTINCT b2.group_id
FROM user u JOIN
belongs b
ON u.user_id = b.user_id and b.group_id = '1' JOIN
belongs b2
ON b2.user_id = b.user_id;
One way to choose a random such group is to use order by rand() limit 1. You might want to add where b2.group_id <> '1'.
Assuming that you want to count the members of group_id = 1 in these groups, you would just use group by:
SELECT b2.group_id, count(distinct b2.user_id) as numusers
FROM user u JOIN
belongs b
ON u.user_id = b.user_id and b.group_id = '1' JOIN
belongs b2
ON b2.user_id = b.user_id
GROUP BY b2.group_id;
The join to user is superfluous, but I have left it in assuming that it might be used for some other conditions not in the original question.
You can get a list of all the other groups associated with people in group 1 by using a sub-query:
SELECT g.group_name, COUNT(g.group_name)
FROM group g
INNER JOIN belongs b ON b.group_id = g.group_id
WHERE b.user_id IN ( SELECT u.user_id FROM user u JOIN belongs b ON u.user_id = b.user_id and b.group_id = '1' )
GROUP BY g.group_name
ORDER BY COUNT(g.group_name) DESC
With a Left Join i have this result.
Here the screen
http://f.cl.ly/items/373Y141r1K131d0n3f1q/Schermata%202013-04-01%20alle%2016.51.18.png
i want to show only record once time, without repeat it, but with a left join all my records are different.
what i have to do for show once all my records?
the query.
SELECT * FROM login_users
LEFT JOIN login_users_seguaci
ON login_users.user_id = login_users_seguaci.following
WHERE name LIKE ""
AND user_id != '1'
ORDER BY data DESC
SELECT x.*, y.*
FROM login_users x
LEFT JOIN
(
SELECT a.*
FROM login_users_seguaci a
INNER JOIN
(
SELECT following, MAX(DATA) max_data
FROM login_users_seguaci
GROUP BY following
) b ON a.following = b.following AND
a.DATA = b.max_date
) y ON x.user_id = y.following
// WHERE ... your condition here ...
ORDER BY t.data DESC
// Edit:
All work fine with:
SELECT u.*,
l.cod AS loans_cod,
l.step AS loans_step
FROM users AS u
LEFT JOIN loans AS l
ON u.id = l.users_id
WHERE l.step < 12
OR NOT EXISTS
(SELECT l.id
FROM loans
WHERE l.users_id = u.id
)
GROUP BY u.id
Now, I can select all user, and his last loan. Thanks, and I think my solution will help future users.
if you want the last loan, you could append something like this
ORDER BY l.date DESC GROUP BY u.id
SELECT u.*,
l.cod AS loans_cod,
l.step AS loans_step
FROM users AS u
LEFT JOIN loans AS l
ON u.id = l.users_id
WHERE u.id != :id
AND l.timestamp = (SELECT MAX(l.timestamp)
FROM loans AS l2
WHERE l2.users_id = l.users_id)
Where timestamp is a column on your table that indicates when the loan was created or otherwise gives you a time that you can compare to.
Try this:
SELECT u.*, l.cod AS loans_cod,
l.step AS loans_step
FROM users AS u inner join
(
select max(l.loan_id) as loan_id, l.users_id , l.cod, l.step
from loans l
group by
l.users_id,l.cod,l.step
) as l
ON u.id = l.users_id
WHERE u.id != :id
Note: Avoid doing select * it's a very bad practice. List all the columns you need only.