SQL - Return books that user owns - php

I'm doing I'm having a bit of a problem performing a query in my university project. I got a website where users share the books that they've read and I have a page where the user can view the books he has added (the books he owns).
For that I believe I need the logged user's id, which I store in a session PHP variable, the user id is in table users.
The information about the books is stored in a table books and it has its own id primary key.
Then, to show who owns what I have a table owns_book (id, u_id, book_id).
Right now for testing I've got 26 books total, 25 of them are added by a user with id of 57 and 1 book by user with id of 49.
When I run this query:
SELECT id, title, author, category, cover, added, user_id FROM books, users
WHERE user_id=49 AND id IN(SELECT book_id FROM owns_book)
AND user_id IN(SELECT u_id FROM owns_book)
And the result is a mess, I don't get the expected one book, I also get books added by the other user.
Can someone please show me the correct query that I need or if I need to change the structure of my tables? Thanks.
EDIT:
users(user_id, ...)
books(id, title, author, publisher, published, cover... )
owns_book(id, u_id, book_id)

It looks like you're looking to to grab everything from your books table that is owned by a specific customer. If that's the case, you can try
SELECT * FROM books
JOIN owns_book
ON books.id = owns_books.book_id
WHERE owns_book.user_id = 49
This will select all of the props from your books table then joins the tables based on on the ID of the book being equal to the book_id of the owns_book. Lastly, add the parameter - you only want to see user_id = 49.

You can simplify this query and use a LEFT JOIN...
SELECT books.id, title, author, category, cover, added, users.user_id
FROM users
LEFT JOIN owns_book on owns_book.user_id = users.user_id
LEFT JOIN books on books.id = owns_book.id
WHERE users.user_id=49
This links the user_id and lists any books owned by this user_id ( the ON bit of the JOIN). The WHERE clause just limits to listing records for the user_id your after.
If in the main list of columns, there is a column on multiple tables ( like user_id) then prefix it with the table name to allow the database to detect which column you want to use (even though they may be the same value).

You could also use inner join to join the tables users and books with the owns_book table:
SELECT id, title, author, category, cover, added, user_id
FROM owns_book
INNER JOIN users ON users.id = owns_book.u_id
INNER JOIN books ON books.id = owns_book.book_id
WHERE users.user_id=49

Related

MySQL join only latest row

I have 3 tables with following column names:
restaurants:
id, name, cuisine, address, image_file
reviews:
id, restaurant_id(foreign key), user_id(foreign key), header, content, posted_at, modified_at
users: -id, username, email, password, privileges
In my PHP project on the main page where i want to display all the restaurants with the latest review if there is any review. Can someone please help me how to do that within single query and single foreach loop? I've tried left join with subqueries but could not resolve the problem of duplicated rows. Thanks in advance!
Try this
SELECT *
FROM restaurants
LEFT JOIN
(
SELECT restaurant_id AS restId, MAX(posted_at) AS lastTime
FROM reviews
GROUP BY restaurant_id
) AS last_reviews
ON last_reviews.restId = restaurants.id
LEFT JOIN reviews
ON reviews.posted_at = last_reviews.lastTime
AND reviews.restaurant_id = restaurants.id

MySQL INNER JOIN with different column names

Okay, so I have two tables, a news table and a users table. They are set up as below:
news:
id title user_id contents
users:
id username password
When I run this query:
SELECT news.title, users.username, news.contents FROM news INNER JOIN users ON news.user_id=users.id WHERE news.id=:id
I can only access the user id using $query['id']. So it appears that the join is using the column names from table2, although I want them to map it to the column names of table1. So even though the column is called id in the users table, I want to access it under user_id, since I specified that in the JOIN query.
I need this because if I ever need the id from table1, they would both be mapped to the column called id and I would only be able to get the id of the users table.
So is there any way to do this? Access the column from table2 under the name of the column in table1?
In MySQL what you specify in the select statement is what it is called in the result set, so you need to tell it what to give you. you do that with the AS command
SELECT users.id AS user_id ... FROM ...
That way you can call it whatever you want
or grab the user_id from news with
SELECT news.user_id ... FROM ...
SELECT users.id AS id1, news.id AS id2, news.title, users.username, news.contents
FROM news INNER JOIN users ON news.user_id=users.id WHERE news.id=:id
echo $query['id1'] . $query['id2'];

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

Create news update with comments, how to join tables?

I want to create a news update system, using MySQL and PHP. But i can't get it working, having trouble with the join satement and PHP, so i can display a news update and all the comments attached (and if a valid user is logged in, the person can delete each comment individually). But it is only the JOIN statements i'm having trouble with.
I have these tables and DB schema
news_tbl (news_id, date, user (fk to users_tbl.username), headline, bodytext and picture)
users_tbl (username, email, password, usertype)
comments_tbl (comments_id, name, comment, news_id(fk to news_id))
I have tried with this:
$sqlquery ="SELECT news_tbl.*, users_tbl.*, comments_tbl.*,
COUNT(comments_tbl.comments_id) AS comments_count
FROM news_tbl
LEFT JOIN users_tbl
ON news_tbl.user = users_tbl.username
LEFT JOIN comments_tbl
ON comments_tbl.news_id = news_tbl.news_id
GROUP BY news_tbl.news_id ";
But then i can only display one comment, and i want all the comments, and i want to fecth the ID of each comments, so the user can delete each comment individually. And also i cannot get a news id, if a comment isn't written?
This should get roughly what you want,although you should always share your query and also specify exactly what you pretend to achieve.
Select ut.user_id,nt.news_id,nt.headline, nt.body,ct.comments_id,
ct.comment,count(ct.comments_id) as total
from news_tbl nt
inner join users_tbl ut on ut.user_id=nt.user_id
left join comments_tbl ct on ct.news_id=nt.news_id
group by ut.user_id,nt.news_id
good luck.

How to call specific rows from a table in MySQL ? (see the case)

The website is intended for users to enable them joining the courses and posting their updates to these courses and also receiving the course updates made by others (imagen courses as Groups in Facebook but in my website users post updates ONLY through the courses)
When the user login to the website, he is suposed to see all the updates in the courses he already is joined in.
I have many tables in MySQL :
'updates' which have these attributes (id, account_id,course_id,datetime,content) noticing that course and account ID's are foreign keys..
'courses' which have these attributes (id,name,..)
'accounts' which have these attributes (id,full_name,...)
'accounts_courses_relationship' (account_id,course_id) , to map the relations between users and courses.
I have tried many times but the only thing I get is to show all the updates for all courses without excluding the updates from the courses that user isn't a member of, as follow:
$sql = "SELECT DISTINCT datetime, content
FROM updates
WHERE account_id != {$account_id}
ORDER BY datetime DESC
LIMIT 10";
So, How to exclude the updates from these courses?
Note: don't forget that all mappings between users and courses are registered in a table shown above..
Well i might be not seeing your problem it but how about
SELECT ... FROM updates where account_id = {$account_id}
Would't this select all updates for the current user and therefore all the updates the user is interested in?
something like this should work
select *
from updates u
join accounts_courses_relationship r on u.courseid = r.courseid
where r.account_id = {$account_id}
You have to inner join the updates and courses and accounts and accounts_courses tables.
select acr.accountid, acr.courseid, courses.name, accounts.fullname, updates.datetime, updates.content
from accounts_courses_relationship acr
inner join courses on acr.courseid=courses.courseid
inner join accounts on acr.accountid = accounts.accountid
inner join updates on updates.accountid= accounts.accountid and updates.courseid=courses.courseid
where accountid = {?}
order by updates.datetime desc
If you're interested in seeing updates to courses from other users (not you) and you're a registered user of those courses:
SELECT DISTINCT datetime, content
FROM updates
WHERE account_id != {$account_id}
and course_id in (select acr.course_id from accounts_courses_relationship acr where acr.account_id = updates.account_id)
ORDER BY datetime DESC
LIMIT 10

Categories