While creating a local movie database, I have 3 tables with below structure:
TABLE1: movies
movie_id | movie_title
TABLE2: categories
category_id | category_title
TABLE3: categories_movies
id | movie_id | category id
1 movie can have multiple categories, I'm trying to display each movie with its categories, example:
MOVIE TITLE 1 (Category 1, Category 2, Category 3)
MOVIE TITLE 2 (Category 2, Category 3)
Currently I do with 3 queries, first I select all movies:
select * from movies
Then
select * from categories_movies where movie_id = $movie_id
Then
select * from categories where category_id = $category_id
I've tested with some inner join, but no good idea, since 1 movie can have multiple categories.
Any suggestion will help, thanks.
I didn't fully understand what is the format you want to display it, but you can use GROUP_CONCAT() if you want to display it as 1 column:
SELECT m.movie_title,GROUP_CONCAT(c.category_title)
FROM movies m
INNER JOIN categories_movies cm
ON m.movie_id = cm.movie_id
INNER JOIN categories c
ON cm.category_id = c.category_id
GROUP BY m.movie_title
If you just want them to be displayed as separate rows:
SELECT m.movie_title,c.category_title
FROM movies m
INNER JOIN categories_movies cm
ON m.movie_id = cm.movie_id
INNER JOIN categories c
ON cm.category_id = c.category_id
i think you need to use left join :
SELECT m.movie_title,c.category_title
FROM movies m
LEFT JOIN categories_movies cm
ON m.movie_id = cm.movie_id
LEFT JOIN categories c
ON cm.category_id = c.category_id
SELECT movies.movie_title, GROUP_CONCAT(`category_title` SEPARATOR ',') as category
FROM `categories_movies`
left join categories on categories.category_id=categories_movies.category
left join movies on movies.movie_id=categories_movies.movie_id
GROUP BY categories_movies.movie_id
You can use GROUP_CONCAT().It works perfectly:
SELECT movies.movie_title, GROUP_CONCAT( categories.category_title )
FROM movies
INNER JOIN categories_movies ON movies.movie_id = categories_movies.movie_id
INNER JOIN categories ON categories_movies.category_id = categories.category_id
GROUP BY movies.movie_title;
Related
assuming we have a database category structure like this
# Categories Table
| category_id | parent_category_id | status |
# Products Table
| product_id | category_id |
how do i get the list of products in a category only if the parent_category_id has an active status = 1 ?
i guess i could use some sub-query in the SELECT statement, but i don't know how! :(
something like:
SELECT p.*, (SELECT * FROM ? WHERE ? ) AS x
FROM products AS p
LEFT JOIN categories AS c ON p.category_id = c.category_id
WHERE ...
AND p.product_id = '?'
AND ...
Thank you in advance for any advice!
NB: i'm using PHP as backend language, just in case i need some sort
of data manipulation to pass to the mysql query.
try not to use subquery, because it can affect the speed of loading data
maybe it can help
SELECT *
FROM categories c
INNER JOIN products p ON p.category_id=c.category_id
WHERE c.status = 1
Here a example query, I don't use left join or join, becasue you require that the record exists in order to get the status.
SELECT
*
FROM
products, categories
WHERE
products.category_id = categories.category_id
AND status = '1'
SELECT p.* FROM products p
INNER JOIN categories child ON child.category_id = p.category_id
INNER JOIN categories parent ON parent.category_id = child.parent_category_id
WHERE parent.status=1
First you have to get all active categories
SELECT child.*
FROM Categories child
JOIN Categories parent
ON child.parent_category_id = parent.category_id
AND parent.status = 1
But you also need the root categories with not parent_id
SELECT *
FROM Categories
WHERE parent_category_id IS NULL
AND status = 1
So you UNION both
SELECT *
FROM Categories child
JOIN Categories parent
ON child.parent_category_id = parent.category_id
AND parent.status = 1
UNION ALL
SELECT *
FROM Categories
WHERE parent_category_id IS NULL
AND status = 1
Now you get the products for those categories
SELECT *
FROM ( ... UNION ALL ... ) active_categories
JOIN Products
ON active_categories.category_id = Product.category_id
i have a table food
food_id food_name
1 chappathi
and another table category
category_id category_name
1 non-veg
2 nutrition
and a relation table food_category
food_id category_id
1 1
1 2
where the food_id is the foriegn key of food_id in food table, category_id is the foriegn_key of category_id in the category table, there will be case no categories for a food
i have tried
$sql= "SELECT * FROM food f
LEFT JOIN food_category fc
ON f.food_id=fc.food_id
LEFT JOIN category c
ON fc.category_id=c.category_id"
it gives me more than one food items, what i want is
item name: chappathi
categories: non-veg, nutrition
------------------------------
second row of result set if there is any
Try this:
SELECT f.food_name AS item_name, GROUP_CONCAT(c.category_name SEPARATOR ', ') AS categories
FROM food f
LEFT JOIN food_category fc ON f.food_id=fc.food_id
LEFT JOIN category c ON fc.category_id=c.category_id
GROUP BY f.id
Hope it will help you.
Agreed with #strawberry. Look at group_concat.
http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html#function_group-concat
The query should be written as below to fetch the food name and its categories list.
SELECT f.food_name as ItemName,
STUFF(
(SELECT DISTINCT ',' + c.category_name
FROM food
LEFT JOIN food_category fc on fc.food_id= food.food_id
LEFT JOIN category c ON fc.category_id =c.category_id
FOR XML PATH ('')), 1, 1, '') AS Categories
FROM food f
group by f.food_id, f.food_name
Please check it out.
What you need is group_concat:
SELECT f.food_name, group_concat(c.category_name) AS Cat
FROM food AS f
LEFT JOIN food_category AS fc ON f.food_id = fc.food_id
LEFT JOIN category AS c ON c.category_id = fc.category_id
GROUP BY f.food_id
Let's say i have 3 tables:
table: SONGS
cell: ID primary key
cell: TITLE
cell: ADD_TIME
table: CATEGORIES
cell: ID primary key
cell: title
table: SONGS_CATEGORIES
cell: ID primary key
cell: SONG_ID
cell: CATEGORY_ID
Then let's assume that I have 3 songs(with id's 0, 1, 2), and I have 5 categories(rock, pop, rap and so on) and respectively, their id's(0, 1, 2...). How my sql query should look like, if I want to be able to select more than one category, then I need to look into table SONGS_CATEGORIES and get all songs_id with category id I selected, and then i get songs from table SONGS with those id's?
Hope i explained what i need pretty well, English is not my native language.
If you already know the ID numbers of the categories that you're wanting songs from then the following should do the trick:
SELECT *
FROM SONGS s
JOIN SONGS_CATEGORIES sc
ON s.ID = sc.SONG_ID
WHERE sc.CATEGORY_ID IN (#id1, #id2, #id3...#idN);
If you only know the names of the categories you want the songs for then you can use this:
SELECT *
FROM SONGS s
JOIN SONGS_CATEGORIES sc
ON s.ID = sc.SONG_ID
JOIN CATEGORIES c
ON sc.CATEGORY_ID = c.ID
WHERE c.title IN (#catTitle1, #catTitle2, #catTitle3...#catTitleN);
In both of these examples you would replace the # with the data you are providing and adjust the SELECT part to show only the columns you need.
If you want to select songs from categories 1 & 2 :
SELECT s.id song_id, s.title song_title, s.add_time song_add_time, c.id cat_id, c.title cat_title
FROM CATEGORIES c
INNER JOIN SONGS_CATEGORIES sg
ON c.id = sg.category_id
INNER JOIN SONGS s
ON sg.song_id = s.id
WHERE c.id = 1 OR c.id = 2
I guess this is what you need
SELECT * -- select what ever columns you need to display
FROM SONGS s
JOIN SONGS_CATEGORIES sc
ON s.ID = sc.SONG_ID
JOIN CATEGORIES c
ON c.ID = sc.CATEGORY_ID
where c.title in ('title1','title2')
I got 2 tables:
1 Category
- cID
- Name
- Active
2 Products
- pID
- Name
- category_id
- active
This is want i want:
I want a list from categories that ONLY have ACTIVE products.
Thanks in advance
SOLUTION:
SELECT DISTINCT category.* FROM category INNER JOIN products ON category.id = products.c_id WHERE products.active = 0 ORDER BY category.id DESC
Assume Products.Active = 1 means active state.
SELECT c.*
FROM Category c
INNER JOIN Products p ON c.CID = p.category_id
GROUP BY c.CID
HAVING COUNT(*) = SUM(IF(p.Active = 1, 1, 0))
I'd suggest construction like this
IMHO, it's syntax shows what you really want to see - all categories that have active products
select C.cID, C.Name, C.Active
from Category as C
where C.cID in (select distinct T.category_id from Products as T where T.Active = 1)
SELECT * FROM Products
Join Category on Category.ciD = Products.category_id
WHERE Category.Active = 1 AND Products.Active =1
This is assuming your active columns are just 1 or 0. Otherwise adjust according to what values you're storing there.
I'm really sorry for the first post as i didn't explain everything.
Basically i have 3 tables, One for posts, One for Categories, & Another to link categories with posts.
I want in a single MySQL query to select posts that are under a specific category.
posts(id,title,body)
---------------------
125,Some title,Blah blah
categories(id,name)
---------------------
1,politic
2,entertainment
linker(categoryid,postid)
---------------------
2,125
I want in single query to fetch posts in the entertainment category by example, what to do?
Thanks
select
p.*
from
posts p
inner join linker l on l.postid = p.id
inner join categories c on c.categoryid = l.categoryid
where
c.name = 'entertainment'
The following SQL statement should provide you with a basis for what you are trying to do.
select p.*
from posts p
inner join linker l
on l.postid = p.id
inner join categories c
on l.categoryid = c.id
where c.name = 'entertainment'
If a post belongs to 2 categories, you can still use pinkfloydx33's query with DISTINCT in the select statement:
select
DISTINCT p.*
from
posts p
inner join linker l on l.postid = p.id
inner join categories c on c.categoryid = l.categoryid
where
c.name = 'entertainment'
The result set will show only one record.
It's the same exact thing, you just have to join 3 tables intead of 2 :
SELECT P.id post_id,
P.title,
P.body,
C.id category_id,
C.name
FROM posts P
INNER JOIN linker L
ON P.id = L.postid
INNER JOIN categories C
ON L.categoryid = C.id
WHERE C.name = 'Category'
Don't be afraid to do your own tests. If you understand how to join two tables, you should understand how to join three, four and more.
If you are specifying only one category in the WHERE clause, then the result will be a single row for each post ID.
Either way you can use DISTINCT or GROUP BY when the result could be more than one row per ID, but in that case i prefer the second one (GROUP BY).