Lets guess I have 3 tables:
Table a where I have a name and email
Table b where I have a text and user (as a reference to email from table a)
Table c where I have follower and following (both references to email in table a)
Im trying to develop a simple html/php/sql web that allows me to register many users and let them post different texts while also having the chance to follow or be followed by other users (already done) and I want to give an user the possibility to display the texts from table b that he himself posted and those from the users he is following
Im seriously struggling with how to extract this information
SELECT b.text
FROM tableB as b
LEFT JOIN tableC as c
ON b.user = c.follower
WHERE b.user = "currentuser"
This is as far as I got, which only shows the texts posted by the user himself (something I can do way more simple) but I cant seem to understand how to get those from the users he is following
I hope its understandable without any photo
You first want to find all following users in table c rows where the current user is the follower. Then you want to add the current user (or alternatively always have all users follow themselves). Then you want to find all texts for those users.
So:
select b.text
from (
select following as user
from tableC
where follower="current user"
union
select "current user"
) show_users
join tableB as b on b.user=show_users.user
or if you have a tableC row where follower=following for all users, just:
select b.text
from tableC as c
join tableB as b on b.user=c.following
where c.follower="current user"
Related
I have 3 tables: person, image and comment. Person has fields id and name. Images are for a specific person so it has id, person_id, image_name. And comment is kind of a hybrid table because a comment can be either directly for a person or for an imaga - so it has fields id, person_id, image_id and comment.
The same table was used for both comments because the comment plugin is identical for both cases and i also need to show all comments in a live feed so it seemed easier to keep them in one table.
My problem now is tho how can i write a query that gives me all the relevant data reardless if comment is for person or for image.
Select should return a row for each comment with additional data:
comment
image_name (if comment is tied to image_id)
person_name (regardless if comment is tied directly to person or to an image)
The problem im facing is I don't really know how to select person through image if image_id is present and otherwise select person directly through person_id. Also its kind of hard to search for this kind of a solution because its hard to put it in words.
Edit, added sqlfiddle:
http://sqlfiddle.com/#!9/7fa06a/1
The thing that is currently missing is the person data for second row. That data should be available because image table has person_id but i dont know how to select it.
Solution seemed to be to join person table with both person and image using OR and depending which one is present it gets joined:
SELECT *
FROM comment
LEFT JOIN image ON image.id = comment.image_id
LEFT JOIN person ON person.id = image.person_id OR
person.id = comment.person_id
You need to make comment table as main table and then left join person and image tables.
Select * from comment c left join person p on p.id=c.person_id left join image i on i.image_id=i.id and i.person_id=c person_id
You could do that with COALESCE(). It returns the first argument that is not NULL.
SELECT comment.comment, image.name, COALESCE(person.name, image_person.name)
FROM comment
LEFT JOIN person on person.id = comment.person_id
LEFT JOIN image ON image.id = comment.image_id
LEFT JOIN person image_person ON image_person.id = image.person_id
The answer of user1985273 should more efficient, though.
I've been following the PHP Authentication Tutorial en managed to get it working.
Now I want to add a function to my navbar. I will try to explain and hopefully someone has the answer.
I have the 2 user tables, users and user_permissions.
In the user table there are additional columns named district_id, district, gemeente_id and gemeente. I also have 2 extra tables in the database called districten and gemeenten.
The districten table has 2 colums. id and district which holds the unique ID and the name. The gemeente table has at least these 3 columns id, district_id and gemeente.
Here is what I would like to happen:
When the user logs in the query will give a result in an <ul> in the navbar where it will show all values (column gemeente) from the gemeenten table where the user has been assigned to.
Example:
User ZZZ is assigned to district A.
This district holds 4 gemeenten : City 1, City 2, City 3 and City 4
When the user logs in, he should
only see the cities from the District A.
I don't know how to get this working in Slim2 Framework and integrated in the PHP Authentication code. So any help is much appreciated.
First you have to normalize your table and get rid of redundant information since it's hard to maintain it in relational database(I assume here you're using relational database like MySQL).
So basically each user is assigned to gemeente, each gemeente assigned to district and district in his turn has cities(gemeenten). In user table you only need the gemeente_id. The schema of districten and gemeente seems fine.
There are two way how to retrieve needed data: by running 2 queries(1 for fetch user's district; 2nd for fetch district's cities) and run everything in one query. Which way to choose is up to you.
1st approach:
SELECT d.id FROM district AS d LEFT JOIN gemeente AS g ON g.district_id=d.id LEFT JOIN user AS u ON u.gemeente_id=g.id WHERE u.id=<user_id>
SELECT g.id, g.gemeenten from gemeente as g where g.district_id = <res_of_prev_query>
2nd approach:
SELECT
g.id, g.gemeenten
FROM gemeente AS g
LEFT JOIN
districten AS d
ON g.district_id=d.id
INNER JOIN (
SELECT DISTINCT district_id, u.id AS user_id
FROM gemeente as gg
INNER JOIN user AS u
ON u.gemeente_id=gg.id) AS ud
ON ud.district_id=g.district_id
WHERE ud.user_id=<user_id>
You need transform this query to your ORM/ActiveRecord, run it and display the ul list
UPD: I've updated my answer. Thanks #DarkBee for pointing me to my mistake
I have 5 tables:
user ( user id, user name, etc.. )
role ( role_id, role_name )
user_role ( user_id, roles_id )
form ( form_id, form_name, etc.. )
form_access ( form_id, role_id )
user contains all registered user data.
role contains all different types of roles.
user_role contains which user has which role (all assigned roles are stored)
form contains all form data.
form_access contains data like which user role has which form access(one form can be assigned to many user roles).
I wanted to write a SQL query in PHP to retrieve form name based on the user logged in and his role, e.g. if Admin logs in he should get all forms, if HR logs in he should get forms related to HR only.
I tried this query:
$query = "SELECT ur.role_id, f.form_name, f.form_desc
FROM user_role ur, froms f
WHERE users.id = '".$user."',
users.status ='A',
forms.form_id = form_access.form_id,
from_access.role_id = user_role.role_id,
user_role.role_id = '".$user."'";`
Some one help me out with the correct query?
Since you start from the user_id you'll want to select from user_role and JOIN form_access and form.
SELECT `form`.`form_name` AS `form_name`
FROM `user_role` AS `ur`
INNER JOIN `form_access` AS `fa` ON `fa`.`role_id` = `ur`.`role_id`
INNER JOIN `form` AS `f` ON `f`.`form_id` = `fa`.`form_id`
WHERE `ur`.`user_id` = '".$user."'
PS: Check the table and column names.
You have to use AND .
BUT this should be better with joins.
$query = "SELECT ur.role_id, f.form_name, f.form_desc
FROM from_access
INNER JOIN froms f ON forms.form_id = form_access.form_id
INNER JOIN user_role ur ON from_access.role_id = user_role.role_id
INNER JOIN users ON users.id = user_role.role_id
WHERE users.id = '".$user."'
AND users.status ='A' ";
Your query is entirely broken, the others may have provided you with solutions but I'm going to give you some advice.
You've written an entire query, tried it, and it failed. I write queries all day long but if I write a whole query in Notepad then execute it it's probably going to have some minor error in it somewhere too.
Start from the ground up. You're trying to get a list of forms the user has access to, so lets start with the forms_access table. So what's the most basic starting point? How about:
SELECT fa.role_id, fa.form_id
FROM forms_access fa
Ok, thats overly simplified but if that ran at least we know we're connected to the database.
So we can easily tell which form_ids each role has access to. Now we know our linking table to users is user_roles, so let's add that in:
SELECT ur.user_id, fa.form_id, fa.role_id
FROM forms_access fa
INNER JOIN user_roles ur ON fa.role_id = ur.role_id
So we've joined forms_access to user_roles on the foreign key role_id. Now we can see for every user_id, which role_id they have and which form_ids they can access.
So we're pretty much there, we just need the information from the forms table, so lets JOIN to that too:
SELECT ur.user_id, f.form_name, f.form_desc, fa.form_id, fa.role_id
FROM forms_access fa
INNER JOIN user_roles ur ON ur.role_id = fa.role_id
INNER JOIN forms f ON f.form_id = ur.form_id
Great! Now we have a list of each form_name/form_desc that each user_id can access.
Try the above step by step, if you skip to the end there could well be an error since I have not tested the code, and I don't know for sure that your table definitions match the question. If you do it step by step you only need to check the most recently added line to find the error.
I have just noticed in the question that you also need users.status = 'A', so in the same way as above you'll need to join to the users table on an appropriate foreign key, give it a go.
Now, once you've done all that you need to filter the results to a specific user_id - notice up till this point we haven't bothered with the WHERE clause.
Now don't go adding some variant of WHERE user_id = '$user' right away because then you've introduced 2 potential errors. Instead try adding WHERE user_id = 0 (or some known user_id). Does the query run and the results look correct? Great, now finally try adding in your php variable.
I have two separate tables. I need to SELECT the avatar from the user table, WHERE the username equals from on the comments table. I am trying to create a comment system that displays the user's avatar next to their message.
Comments - ID|Username|From|Timestamp|Message
User - ID|Username|Avatar
$fetchto=mysql_fetch_object(mysql_query("SELECT * FROM user WHERE username='$variable'"));
I think I could display the URL to the avatar using $fetchto->avatar if I had a variable that would pull the avatar of the member making the comment from the user table.
First off your database isn't properly normalized. The comments should refer to the User by UserId, not by Username. Once you've fixed that:
select * from Comments c
join User u on u.ID = c.UserId
Until then:
select * from Comments c
join User u on u.UserName = c.UserName
Also, please stop using the mysql_ family of functions - they're deprecated.
Your query needs to have a simple join, something like this:
SELECT c.*, u.avatar
FROM comments AS c
JOIN user AS u ON c.username = a.username
I am writing an application that helps book exchange between users.
I am using PHP and MySQL, and I am pretty new to them both.
I have 5 tables, 3 data tables and 2 service tables:
user: with user attributes (user_id, name, birth... etc).
book: with book attributes (book_id, name, author, publisher... etc).
copy: represents actual copies of a books (copy_id, condition, comments... etc).
user_copy: describes which user holds which copy, composed out of userID and copyID.
copy_book: represents the connection of copy and book, composed out of copyID and bookID
My question is:
what is the easiest and most efficient statement for getting the
book attributes and copy attributes for each copy that a user holds?
You need to inner join all the tables that you are interested in: book, copy, user_copy, and copy_book. The SELECT statement that returns attributes on all copies held by a user may look like this:
SELECT B.bookID
, B.name
, B.author
, B.publisher
, C.condition
, C.comments
-- you may get other fields that you are interested in here..
FROM book B
INNER JOIN copy_book CB ON B.bookID = CB.bookID
INNER JOIN user_copy UC ON UC.copyID = CB.copyID
INNER JOIN copy C ON C.copyID = UC.copyID
WHERE UC.userID = <the user Id that you want>
I hope it's pretty clear what the statement does but if you have any questions, please ask.