relations in SELECT query (PHP) - php

I have little problem with SQL query in PHP.
I want to get from table post rows with category ex. 'art'.
This table don't contain name of my category (only category_id).
So, how to connect this in my query?
Tables:
post:
id, title, category_id
category:
id, name
I tried this way, but it not works.
SELECT * FROM post WHERE category_id = category.id AND category.name="art";
Anyone can help me? Thanks.

You need to join the tables.
Given your schema, this should give you an starting point:
SELECT p.* FROM post p INNER JOIN category c ON p.category_id = c.id WHERE c.name = 'art';

You are missing the JOIN
SELECT * FROM post
INNER JOIN category
WHERE category_id = category.id AND category.name="art";

You need to use join to query on name column of category table, e.g.:
SELECT p.*
FROM post p JOIN category c ON p.category_id = c.id
WHERE c.name = 'art';

Related

MySQL - WHERE / HAVING count

I searched lots of similar topics about this but can't find the answer to this specific probem.
So I have a table with categories and I have another table with products, so what I want is select all the categories that contain at least 1 product, seems very easy but the following code dont give me what I expect.
SELECT *
FROM categories
INNER JOIN products on (categories.id = products.cat_id)
HAVING count(products.cat_id) > 0
All help is appreciated.
Thank you!
You can actually get what you want with just a join because any categories without products will not match.
You should also add a DISTINCT or GROUP BY to remove the duplicate category records from the results:
SELECT DISTINCT c.*
FROM categories c
JOIN products p
ON c.id = p.cat_id
OR:
SELECT c.*
FROM categories c
JOIN products p
ON c.id = p.cat_id
GROUP BY c.id
If you want something fancy like categories that have 2 or more products then you can use GROUP BY and HAVING:
SELECT c.*
FROM categories c
JOIN products p
ON c.id = p.cat_id
GROUP BY c.id
HAVING count(*) >= 2
Try this select in this select all categories that have at least one product
select categories.* from categories
left join products on (categories.id = products.cat_id)
where products.cat_id IS NOT NULL
group by categories.id
In this case you're not using "HAVING" but will have the same result

SQL Join question

I have a table vm_category in which I fetch all rows from the category_id and caregory_name columns. I then use this in a drop-down to populate a search-filter module on the left side of the side.
Now doing so gives me a gigantic list of categories, and I'd like to narrow it down by category's sub-category. Those are organized in another table called vm_category_xref in which I have 3 columns;
category_parent_id
category_child_id
category_list
What I'd like to do is specify in my query to only return the category_id and names that match a specific category_parent_id in the _xref table. Here is my current query:
$query = "SELECT `c`.`category_name` AS `name` , `c`.`category_id` AS `id`
FROM `#__vm_category` AS `c` ORDER BY `c`.`category_id`;";
I am not familiar with JOIN enough to figure this out, but I know it should be rather simple, and any help would be much appreciated. Thank you!
Try this:
SELECT
c.category_name AS name,
c.category_id AS id
FROM #__vm_category AS c
INNER JOIN vm_category_xref xr
ON xr.category_child_id = c.category_id
WHERE xr.category_parent_id = 5 /* the parent_id you want to filter on */
ORDER BY c.category_id;
Try this:
SELECT c.category_name as name, c.category_id as id
FROM vm_category as c
INNER JOIN vm_category_xref as x ON
x.category_parent_id = c.category_id
ORDER BY c.category_id
Essentially this returns category_name and category_id only for records that have a category_id that equals a category_parent_id in _xref.
SELECT c.category_name AS name , c.category_id AS id
FROM vm_category c
INNER JOIN vm_category_xref x on c.category_id = x.category_child_id
ORDER BY c.category_id
I may have picked the wrong fields to join on but whichever are the 2 same fields in c and x are the ones you should put in the join condition
select vc.category_id, vc.category_name
from vm_category vc, vm_category_xref vcx
where vc.category_id = vc.category_parent_id
SELECT
c.category_name AS name
,c.category_id AS id
FROM
vm_category AS c
join vm_category_xref vcx
on c.category_id = vcx.category_parent_id
where vcx.category_parent_id = ?
ORDER BY c.category_id;
Replace ? with the id you want to match.
If I'm understanding you correctly, you want to retrieve category_name and category_ID only for certain category parent IDs on the xref.
I typically use IN for situations like these.
I'm assuming that category_id in vm_category maps to category_parent_id in vm_category_xref.
So...
SELECT CATEGORY_NAME, CATEGORY_ID
FROM VM_CATEGORY
WHERE CATEGORY_ID IN
(SELECT CATEGORY_PARENT_ID FROM VM_CATEGORY_XREF
WHERE CATEGORY_PARENT_ID IN ('XXX', 'YYY', 'ZZZ'))
XXX, YYY, ZZZ are the IDs for the categories you want.

PHP MySQL item categories

I'm trying to display a list of items with their name and all categories they belong to.
My database structure is:
Items table with Id, Item_Name.
Categories table with Id, Category_Name
Items_Categories table with Id, Item_id, Category_id.
I'd like to display the results in a table with the Item Name, and a comma-delimited list of its Categories' Names. I'm not sure how to do this with a single query. Thanks in advance.
You need to use the GROUP_CONCAT function that is available in mysql:
select i.item_name, group_concat(c.category_name) as categories
from items i
inner join items_categories ic on i.id = ic.item_id
inner join categories c on ic.category_id = c.id
group by i.item_name
I won't write it for you, but you need to use group_concat() function (MySQL).
I must say I did not test this query, but it should be something similar to the following:
SELECT i.Id, i.Item_name, GROUP_CONCAT(c.Category_Name) AS category_list
FROM Items i
JOIN Items_categories ci ON ci.Item_id = i.Id
LEFT JOIN Categories c ON c.Id = ci.Id
GROUP BY i.Id
Note that you can use GROUP_CONCAT to create a comma seperated list.
SELECT i.Item_Name, GROUP_CONCAT(c.Category_Name) AS Category_List
FROM Items AS i
LEFT OUTER JOIN (
Items_Categories AS ic
INNER JOIN Categories AS c ON ic.Category_id = c.Id
) ON i.Id = ic.Item_id
GROUP BY i.Id;

PHP SQL - Joining three tables

I have three tables called product, product_category and category with product_category being the linking table.
How can I join these tables using SQL in PHP?
The linking table has only productID linking to the product table and catID linking to the category.
Something like this?
SELECT
*
FROM
product
INNER JOIN
product_category
ON product_category.productID = product.productID
INNER JOIN
category
ON category.catID = product_category.catID
Your query should look something like this:
Added the requirement that there should be a productId and categoryId from a variable:
$query = "SELECT * FROM
product p
JOIN product_category pc ON p.id = pc.productId
JOIN category c ON c.id = pc. categoryId
WHERE p.id = {$productId}
AND c.id = {$categoryId}";

How to query 3 tables in a single query?

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).

Categories