MySQL join only latest row - php

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

Related

SQL - Return books that user owns

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

query to get a distinct row in one to many mysql table relationship

this is the company table
this is the category table
how do i write a query such that it will select one distinct category and list all the companies that belongs to it.
e.g
school i.e category_id= 1 has two companies that belongs to it such as (Dolly, Abbey scaffold, AP).
Art i.e category_id=2 has one company (Blue script);
this is the query that i have
$query="SELECT distinct company.id, company.company_name, category.category_name FROM company INNER JOIN category ON company.category_id =category.id ";
the query works fine but it keeps repeating the category_name that has many companies belonging to it. i want it to show category_name once and display the company that belongs to it under
select t1.*, t2.company_name
(Select id, category_name
from category) t1
left join
(select category_id, company_name
from company) t2
on t1.id=t2.category_id

SQL SELECT Statement for selecting data from two tables using foreign key

I am just tinkering with SQL as I am trying to get into more complex statements. I don't know this qualifies for it or not but please guide how to go about it.
I have looked at JOINS and some question of Multiple Select Statements but unable to understand them correctly.
I have the following two tables:
emp table:
emp_id, name, address, org_id
books table:
id, emp_id, status, org_id
where emp_id in books table is foreign key referencing emp table.
I need to fetch all the records from books table of a particular org. But along with that I need to get all the data of respective employee like name, address along the result.
Please guide me in the right direction.
Thanks
Try this
select B.*,E.name,E.address from books B
inner join employee E
on B.emp_id=E.emp_id
where B.org_id=1;
I took value of of org_id as 1 for test purpose.
SELECT books.id, books.emp_id, books.status, books.org_id, emp.name, emp.address
FROM books
JOIN emp ON emp.emp_id = books.emp_id
WHERE books.org_id = '3'
As the other said, the org_id from emp table makes no sense. You must remove it from the table.
if you want all records from the books table try this
Select b.id,c.emp_id,b.status,e.name,e.address
from emp_table e
Left join books_table b
on(e.emp_id=b.emp_id)
where e.org_id='3' and b.org_id='3'
You can use this query this will gives you all book record with particular org_id along with all employee record
SELECT * FROM emp as e1
LEFT JOIN books as b1 ON e1.emp_id = b1.emp_id WHERE e1.org_id = 'YOUR_ID'
UNION ALL
SELECT * FROM emp as e1
RIGHT JOIN books as b1 ON e1.emp_id = b1.emp_id WHERE e1.org_id = 'YOUR_ID'
The following query should work for you:
SELECT b.id, b.status, b.org_id, e.emp_id, e.name, e.address
FROM Books b LEFT JOIN Employee e
ON e.emp_id = b.emp_id
WHERE b.org_id = 100
This would be the query for org 100.
It appears that your current schema is not normalized very well:
Employee: emp_id, name, address, org_id
Books: id, emp_id, status, org_id
The two tables both store the org_id, which presumably means the same thing.
This query might give you the results you want. You might want to learn more about joins in SQL. A LEFT JOIN gives you all records from one table, and matching records from another.
SELECT books.*,
emp.name AS emp_name,
emp.address AS emp_address,
emp.org_id AS emp_org_id
FROM books
LEFT JOIN emp ON books.emp_id = emp.emp_id
WHERE books.org_id=?
you can use this for all recors both tables :
select * from books
inner join emp on
books.emp_id=emp.emp_id
where books.emp_id=emp.emp_id

SELECT command denied to user on database that doesn't exist

Been bothered with this for awhile now and i think it might be how i have the joins set up.
I have two tables. Ones is called info which contains all of a users contact information. My second table called numbers has all the phonenumbers for different users. They are related by the primary id of info to the info_id of phonenumbers. I want them to join based on this relationship and I want all the phonenumbers under phonenumbers to join into the single phonenumbers column in info. The current join i am using is this.
SELECT phonenumbers p, info i FROM i.phonenumbers
INNER JOIN p.workphone
ON i.PID=p.info_id
INNER JOIN p.homephone
ON i.PID=p.info_id
INNER JOIN p.mobilephone
ON i.PID=p.info_id
all i get is the SELECT comman is deneied to user on database workphone that isnt evena database.
table info:
PID,
firstname,
lastname,
address,
email,
phonenumbers,
table phonenumbers:
PID,
workphone,
homephone,
mobilephone,
info_id,
The syntax for a join would be nice. All the tutorials just give examples and not an explanation of what the different pieces are.
JOIN syntax is
TYPE_OF_JOIN database.table ON field = field
Since you have
JOIN p.workphone ON i.PID = p.info_id
You're actually telling the DB to look for a database named p, which contains a table workphone.
Doesn't matter that you've created an alias p up in your SELECT fields list. That's a field alias, and they NOT the same as a table alias.

Fine-tuning my MySQL relations database and how to use JOIN on it?

I am very new to mysql and databases, so I need help here...
How should I use JOIN to fetch a record from the tables below, when the only given variable is the ad_id?
category and category options are filled in manually i.e. the users may not alter them. So they are only reference tables, but I am not sure this is how I should do it...
I have 6 tables:
category:
cat_id (PK)
cat_name
category_options:
option_id (PK)
cat_id (FK)
option_name
option_value:
value_id (PK) (AI) // I think this should have Auto Increment
option_id (FK)
classified_id (FK)
value
classified: (THIS IS THE MAIN TABLE YOU COULD SAY)
classified_id (PK) (AI)
ad_id
cat_id
headline
description
area: // I am thinking about moving these fields over to the posters table, right?
area_id (PK)
classified_id (FK)
area
description
Here is how I insert a classified into the tables:
mysql_query("INSERT INTO classified (ad_id, cat_id, headline, description) VALUES ('$ad_id', $cat_id, '$headline', '$description')");
$last_classified_id=mysql_insert_id();
mysql_query("INSERT INTO poster (classified_id, name, email, tel) VALUES ($last_classified_id, '$name', '$email', '$tel')");
mysql_query("INSERT INTO area (classified_id, area, community) VALUES ($last_classified_id, '$area', '$community')");
I am new to JOIN!
Every category has sub options (CARS -> color) and every option has a value.
I want to, only by having the ad_id, select all this information.
How can I do so?
And should I merge the area and posters table?
Also, please take a careful look at my db, and tell me if there is anything I might have missed...
This is really out of my knowledge-base so detailed explanations are appreciated!
Thanks
It looks like you have two fields that could be the primary key in classified: classified_id and ad_id. Then you have two other tables, poster and area, that have a one-to-one correlation with classified. If this is the case, you could put all the fields in classified.
A query to join the tables in your insert statements would like like this:
select
classified.ad_id,
classified.classified_id,
classified.headline,
classified.description AS classified_description,
poster.name,
poster.email,
poster.tel,
area.area,
area.description AS area_description from
classified inner join
poster
on
classified.ad_id = poster.classified_id inner join
area
on
classified.classified_id where
classified.ad_id = 123
This is an example of joining some of your tables to get data from more than one of them:
SELECT c.cat_name, co.option_name, cl.headline
FROM category c
INNER JOIN category_options co ON co.cat_id = c.cat_id
INNER JOIN classified cl ON cl.cat_id = c.cat_id
WHERE cl.ad_id = {Your ad_id}
You can join to any other tables needed in the same way (poster, area).
Edit (response to comment): The 'c', 'cl', and 'co' are aliases for the 'category', 'classified', and 'category_option' tables. They don't have anything to do with the join. Here's a source. When I say FROM category c, that allows me to use 'c' as the a shortcut for the category table. Using aliases allows you to make the select/joins/where clause how I did instead of like this:
SELECT category.cat_name, category_options.option_name, classified.headline
FROM category
INNER JOIN category_options ON category_options.cat_id = category.cat_id
INNER JOIN classified ON classified.cat_id = category.cat_id
WHERE classified.ad_id = {Your ad_id}
Basically it's a shortcut that can save you some typing.

Categories