Exclude results in Mysql, NOT IN - php

I need help to write an SQL but i have no idea in this case how.
Tried many different options but nonthing worked.
I have 2 tables in my mysql database
users (id, name, lastname)
blocked_users (id, user_id, blocked_id)
users table
id name lastname
1 nick james
2 james dean
3 mike bendon
blocked_users table
id user_id blocked_id
1 2 1
2 2 3
Example:
What i would like to do is display all users in users table but exclude in this case
those which are blocked by user_id 2.
So if i'm example logged in as Mike Bendon (id 3 in users table)
i should not be able to se james dean (id 2 in users table) because he has blocked me.

Not sure of how to run that with php, but I think this SQL should do what you asked:
SELECT *
FROM users
WHERE id NOT IN
(SELECT user_id FROM blocked_users WHERE blocked_id = $logged_id);
Edit after comment:
Sorry, I misread the id column name. Should be fixed now.

Try this query:
SELECT *
FROM users
WHERE id NOT IN (
SELECT user_id
FROM blocked_users
WHERE blocked_id=$current_user_id);

Related

Update two or more table

i have three tables.
1st table is tbl_user
id u_name p_list
1 demo1 1,3,
2 demo2 4,3,1,
3 demo3 2,3,
4 demo4 2,5,
Second table is tbl_product
id product_name
1 example1
2 example2
3 example3
4 example4
5 example5
third table is tbl_order_list that show the list of order to the users. tbl look like
id pid uid
1 1 1,2,
2 4 2,
3 3 1,2,3,
4 5 4,
now i want
if i'll update tbl user means if i'll remove pid of column p_list of tbl_user than tbl_user will be updated and also tbl_order_list is update
"Example" if i'll remove 3 in p_list of id 2 from tbl_user than table is look like
id u_name p_list
1 demo1 1,3,
2 demo2 4,1, //(pid =3 is remove of demo2)
3 demo3 2,3,
4 demo4 2,5,
And tbl_order_list is look like
id pid uid
1 1 1,2,
2 4 2,
3 3 1,3, //(uid =2 is remove)
4 5 4,
what is the solution of this problem. i want also if i'll add again pid = 3 in p_list of id = 2 of table user than table look like previous tables.
QUERY (From Comments)
mysql_query("UPDATE tbl_user SET u_name='$userName',slug='$userSlug',password='$userPassword',email='$use‌​rEmail',role='$userRole',p_list='$userList',status='$userStatus',modified_‌​date='$userDate' WHERE id='$uId'");
Help Me
So far, I'm not seeing any real correlation to php, but whatever.
I would highly suggest using a normal form (see database normalization) and deduplicate your data. tbl_order_list is a very bad table, as is tbl_user. tbl_order_list shouldn't have an id field, the uid field should contain exactly one uid and the primary key should be (pid,uid) (so both fields). By that point it should be called tbl_order. If you want a list of all pids for a uid or all uids for a pid - at some point - you can query like this:
SELECT GROUP_CONCAT(uid)
FROM tbl_order
WHERE pid=[your pid of interest]
GROUP BY pid
and vice-versa (replace uid with pid and pid with uid). If you want to query it at the same time with the rest of your userdata:
SELECT u.*, GROUP_CONCAT(o.pid)
FROM tbl_user u
LEFT JOIN tbl_order o ON (u.id=o.uid)
[WHERE u.id=[your uid of interest]]
GROUP BY u.id
(and similarly with the tbl_product).
When using mysql >= 5.7 you can create a view:
CREATE VIEW tbl_order_list AS SELECT pid, GROUP_CONCAT(uid) FROM tbl_order GROUP BY pid.
Adding or Removing an order then would result in deleting/inserting a row in tbl_order.
Summary: Make a table tbl_order (uid,pid) that contains the links between uids and pids (one link per row). Join this table in, when you need the the links. Please don't save "references" as a comma-separated list in a string field unless there is a very very very good reason.
If you infact have a very very good reason, consider adding comma (,) to the beginning and end of your lists, meaning. So:
id pid uid
1 1 ,1,2,
2 4 ,2,
3 3 ,1,2,3,
4 5 ,4,
This way you can safely search, add, remove entries:
SELECT * FROM tbl_order_list WHERE uid LIKE '%,[uid of interest],%'
UPDATE tbl_order_list SET uid=CONCAT(uid,',',[uid to add]) WHERE id=[order to update]
UPDATE tbl_order_list SET uid=REPLACE(",[uid to remove],",",",uid) WHERE id=[order to update]
(and similar for your tbl_user, if you're querying by pid in the tbl_order list, drop the id field.)
If you don't prepend a comma, you might at some point have some problems with consistency.
Anyway, I cannot stress this enough: normalize your database structure unless you have very good reasons not to (and be absolutely sure, they really are good reasons, because usually they aren't)

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 !

MySQL retrieve no of users a user has of user resultset

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;

Mysql Php combining 3 tables

basically in this web app i have an event module where user can create, edit and delete an event also can upload photo for that event. Other users either can involve in particular event by selecting I'm in button or just mentioning the event Sound's Cool.
For now there is 3 tables event_photo (user upload pic will be saved here), event_in and event_cool, now i need an event activity feed, for that i need to combine all 3 tables by grouping them as photo, in and cool. So i need suggestion whether to create a single table to list these activity or should i combine all the results in php. Previously i combine all 2 results in single table but now i want to try something different. There are the table structure.
event_photo table
id photo_url business_id event_id user_id caption added_date
1 1111 12 2 3 test1 20130209t1
2 1122 13 3 4 test2 20130209t4
3 1133 14 2 3 test3 20130209t2
event_in table
id event_id user_id date_created
1 2 3 20130209t3
event_cool
id event_id user_id date_created
1 2 4 20130209t5
2 3 3 20130209t6
Now the feed will be like this, based on date_created desc t6 -> t1
User_3 says cool for Event_3
User_4 says cool for Event_2
User_4 added photo for Event_3
User_3 added photo for Event_2
User_3 attending Event_2
User_3 added photo for Event_2
User_3 added photo for Event_2
Now how the table should be design, i hope this is important questions as this can resolve many problems regarding activity feed.Thanks
An option would be to have your three tables and query them with something similar to:
SELECT *
FROM
( SELECT user_id,
event_id,
date_added as date_created,
'photo' as type
FROM event_photo
UNION
SELECT user_id,
event_id,
date_created,
'event_in' as type
FROM event_in
UNION
SELECT user_id,
event_id,
date_created,
'event_cool' as type
FROM event_cool
) s
ORDER BY date_created
To simplify your code, you could create a view:
CREATE OR REPLACE VIEW v_ordered_actions AS
SELECT *
FROM
( SELECT user_id,
event_id,
date_added as date_created,
'photo' as type
FROM event_photo
UNION
SELECT user_id,
event_id,
date_created,
'event_in' as type
FROM event_in
UNION
SELECT user_id,
event_id,
date_created,
'event_cool' as type
FROM event_cool
) s
ORDER BY date_created;
You can use UNION of course: http://dev.mysql.com/doc/refman/5.1/en/union.html However, this is quite slow. Maybe better to create next table, like activity log, where to store just:
entity_type (in/cool/photo)
entity_id (id of row in target table)
event_id
user_id
date
And select via this. When you have selected that, collect all IDs seperatelly for each target table, and get necessary info from that tables (if necessary) returned as indexed array. Foreach activity feed and assign correct data you need for it.
Hope this can help you.

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