MySQL retrieve no of users a user has of user resultset - php

I have two tables users and parents.
Each user has a unique id and a parent id(this is one who referred him to website).
Parent id of root user is 0.
Users that have same parent id are childrens of that id
users
id
name
email
parents
id
parentId
joiningAmount
i want a query in which i will give id of a parent.
This query should return all of its children with following information
id, name, email, joiningAmount, (No of Childrens this user has)
Is it possible to do this in one query?
If not how should i normalize database in order to complete this in one query.
Any help is highly appreciated.
EDIT:
The users table will contain all the user information
Suppose this is users table.
id name email
1 Admin admin#web.com
2 John John#web1.com
3 Larry Larry#web2.com
4 Jone Jone#web3.com
Registration is possible only by referral.
As admin is not referred by anyone his parentId is 0.
Suppose admin refers larry and john(thus their parent ids are 1) and john bring another user from his referral whose name his jone(thus his parent id is that of john) then parents table should look like this.
Joining amount can be ignored for now as its just part of application.
id parentId joinAmount
1 0 1000
2 1 1000
3 1 1000
4 2 1000
so now i want a query to which if i pass an id of 1(admins id) it should return his children's
id, name, email, joiningAmount, (**No of Childrens this user has**)
2, John, John#web1.com, 1000, 1(as john has 1 child)
3, Larry, Larry#web2.com, 1000, 0

Building on the answer by Unamata Sanatarai, here's the query:
SELECT users.id, users.name, users.email, users.joiningAmount,
(SELECT COUNT(*) FROM users AS children WHERE children.parent_id = users.id ) AS children_count
FROM users WHERE users.parent_id = 3

I suggest placing it into just one database like so
users
- id
- parent_id
- name
- email
- joiningAmount
That way you have only one database and you retrieve everything with a query like:
SELECT id, name, email, joiningAmount FROM users WHERE parent_id = 3

Assuming that you don't change the tables the way suggested (which you probably should) then the appropriate query would be:
SELECT users.id, users.name, users.email, parents.joiningAmount,
(SELECT COUNT(*) FROM parents P WHERE P.parentId=users.id)
FROM users,parents
WHERE users.id=parents.id;

Related

php, MySql subquery from two tables

I'm trying to build a MySql query to produce results based on following:
Table Permissions
user_id blog_id
=========================
1 1
1 2
1 3
2 2
3 1
Table Blog
id name
=========================
1 First Blog
2 Second Blog
3 Third Blog
4 Fourth Blog
I need to select all the records from Blog table and display it based on logged in user id like:
$user_id = $_SESSION['user_id];
Table Permissions contains access for each user allowed to view results from blog table.
So something like:
"SELECT * FROM Blog WHERE id IN()"
but I'm not sure how to access permission table to use it in IN().
So for example if user with id 1 is logged in, this user should be able to see Blogs with matching id's 1,2 and 3.
You can use either a join, or an in() subquery.
select b.* from blogs b
inner join permissions p
on b.id=p.blog_id
where p.user_id=...
Try this:
SELECT * FROM Blog INNER JOIN Permissions ON Permissions.blog_id = Blog.id
This show all users.
Working code here: http://sqlfiddle.com/#!9/aa3e9/14
You can use:
SELECT * FROM Blog INNER JOIN Permissions ON Permissions.blog_id = Blog.id
WHERE Permissions.user_id = 'user_id number'
To get a specific user.

Best method for storing multiple ID's in MySQL for querying large result sets

I would like to save which email lists a client subscribes to. I might have:
email_lists:
ID Name
1 Coupons
2 Monthly Newsletter
3 Company News
Now, users can subscribe to as many lists as they want. So let's say I have three users:
users:
ID Name Lists
1 Bob 1,3
2 Jane 2,3
3 Tom 1
Now I need to do a query to get all user ID's which are subscribed to list #1:
SELECT ID FROM users WHERE Lists LIKE '%1%'
Is there a better way of storing the list ID's for each user where queries can be performed more efficiently?
A third table subscrib would be the best here:
UserId ListId
1 1 // Bob, Coupons
1 3 // Bob, Company news
2 2 // Jane, Monthly Newsletter
2 3 // Jane, Company news
3 1 // Tom, Coupons
And then your query would be something like (for Company news):
SELECT UserId FROM subscrib WHERE ListId = '3';
Or
SELECT s.ListId, u.Email, u.Name FROM subscrib s
LEFT OUTER JOIN users u ON u.ID = s.UserId
WHERE s.ListId = '3';

MYSQL query to exclude records in specific condition

Hey I have the following MYSQL DB structure for 3 tables with many to many relation. Many users can have many cars and cars can be for many users as showing below:
Users
ID | Name
---------
100|John
101|Smith
Cars
ID | Name
---------
50|BMW
60|Audi
Users_cars
ID | UID | CID
---------
1| 100 |50
2| 100 |60
3| 101 |60
I have a page users_cars.php this page have two drop down lists
list of all users
list of all cars
In this page you can select a user from user's list and select a car from car's list then click add to insert into users_cars table.
What am trying to do is to exclude from user's drop down list all the users that have been linked with all the available cars from cars table.
In the example above user's drop down list will just have "Smith" because "John" linked with all cars available (BMW,AUDI), if "Smith" also has the BMW he will be excluded from the list. I need a select query for this condition and i don't want to use any nest select query to count user records inside users_cars table
If I understand what you are after you need to use GROUP BY in your query. So to select all users:
SELECT ID, UID FROM Users_cars GROUP BY UID
and for all cars:
SELECT ID, CID FROM Users_cars GROUP BY CID
That will group results that are the same, so you only get one instance of each user, or one instance of each car.
I hope I understood your question right.
I think you can so this using some programming -
With PHP/mysql -
Get count of all distinct car ID's
Get count of cars for each user. (making sure this lists only unique car ID's)
Loop through all users and in each loop compare the above two and exclude the user where this condition matches.
SELECT *
FROM users
WEHRE id NOT IN (SELECT uid
FROM (SELECT uid, COUNT(cid), COUNT(*)
FORM cars
LEFT OUTER JOIN users_cars ON cars.id = users_cars.cid
GROUP BY uid
HAVING COUNT(cid) = COUNT(*)
Basically, what you want to do is that (if I understood your problem) :
SELECT UID FROM Users_cars WHERE CID NOT IN (SELECT ID FROM Cars);
But carefull, this is a greedy request (depends on the size of the tables of course) and you should better put a flag on the user table and update then when your user uses the last available car (or with a batch) so you don't run the request too often !

Check If Some User ID's Are Friends With The Logged In User In A Single Query

I have a simple friends system on my site. Now I'm trying to create a multi-user group messaging system but only between friends. The "To" values of my messaging system are comma values, I want to check if they all are friend with the person sending the message.
For example, I can get all of a user's friends by the following query:
SELECT relation_setter user_id
FROM users_relationships
WHERE relation_getter = {$logged_in_user}
AND active = 1
UNION
SELECT relation_getter user_id
FROM users_relationships
WHERE relation_setter = {$logged_in_user}
AND active = 1
and I have natasha, reeta as a $_POST['to'] value from my message form which I then convert to user ids and get something like 126152, 112238
Now how do I check if these ids are both friends with the logged in user, in a single query. I don't want to run my is_friend function in a loop, which check if a single userid is friends with the logged in user.
Relationships Schema:
users_relationships
id PK
relation_setter FK user_id
relation_getter FK user_id
active smallint(1)
The relation_setter is the one who sent the friend request. To get all my friends I get all the IDs where my ID is either the relation_setter or relation_getter.
users
user_id PK
name
username
password
etc etc...
Your post offers vague insight into the schema, so I will use some assumptions
You can find all of the ids that match their friends via an IN statement. Since you already have them as numeric values with comma's you could do:
SELECT user_id
FROM users_relationships
WHERE relation_getter IN (126152,112238,123456)
AND active = 1
This will return ONLY the records of friends that match. You then could match the number of rows with the number of elements in the query to determine if they're friends or not. You could also just send to the ones that matched.
EDIT
SELECT user_id
FROM users_relationships
WHERE relation_getter IN (126152,112238,123456)
OR relation_setter IN (126152,112238,123456)
AND active = 1
This will return all user ID's of the person's friends be they the getter or setter and it's active.
EDIT 2
new table
relationships_members
id FK (from users_relationships; not unique)
user_id
Sample of relationships_members would be
id | user_id | relation_setter
--------------------------------------
1 12345 1
--------------------------------------
1 98765 0
--------------------------------------
Then if you queried, you would only receive users_relationships ID that were valid
select distinct a.id, b.user_id as friend
from (
select distinct id as friend
from relationships_members
where user_id = {$logged_in_user}
) a, relationships_members b
WHERE a.id = b.id
and user_id IN (126152,112238,123456)

Twitter-like following system

I am working on a twitter clone in PHP for school, and I have one major problem. I cannot find a way to implement a follower system. There is a table for users, and I want to add a field that holds the ids of all of the users that each user follows.
Should I separate the ids with commas and then split them apart in PHP? And then I need to select all of the tweets from the tweets table that were tweeted by any of the users followers. Is there an SQL command that I can use? Something similar to
SELECT *
FROM tweets
WHERE author='$followeduser'"
but where $followeduser is multiple ids.
Have a USER_MASTER table like this
USER_ID (int)
USER_NAME(varchar(50))
Create a table called USER_FOLLOWERS like this
USER_FOLLOWER_ID // Auto increment-Primary Key for this record
USER_ID (int) // foriegn key to UserId column in USER_MASTER table
FOLLOWER_ID (int) // foriegn key to UserId column in USER_MASTER table
Store the UserId in the first column and store the UserId of the User who follows this user in the Follower_ID column.
So your data will look like this
USER_ID USER_NAME
--------------------------------------
1 SCOTT
2 JARED
3 MARC
4 ERIC
USER_FOLLOWER_ID USER_ID FOLLOWER_ID
--------------------------------------
1 1 2
2 1 3
3 1 4
4 2 1
So this means , The User Scott has 3 followers, Jared, Marc and Eric. User JARED HAS one Follower, that is SCOTT
To get the list of Followers for a user(ex : Scott (ID=1)) , you can do a Join between these 2 tables
SELECT U. USER_ID, U.USER_NAME From USER_MASTER U
INNER JOIN USER_FOLLOWERS UF ON U.USER_ID=UF.FOLLOWER_ID
WHERE UF.USER_ID=1 // 1 is the ID of SCott
Make a join table.
Putting all IDs in a list is not the normalized way and can lead to many many issues.
Have a relations table where you have one column called user and second that is following. So if user 1 is following user 3 and 5, then you would have an entree where user = 1 following = 3 and user = 1 following = 5 (use whatever ID's you want). You also have your Tweets Table where you store all tweets. Youre going to want to make a query that joins the two tables

Categories