User "Categories" table as heading for "SubCategories" - php

I don't know if this is possible at all...
But I need to create an sql query that lists all my Categories with their Sub Categories. Problem is that Categories and Sub Categories are stored in separate tables.
The database structure is as follows: TABLE NAME: "Categories", COLUMNS: "ID, Name"
TABLE NAME: "Sub_Categories". COLUMNS: "ID, Name, Category_ID". The category_ID is used to link each sub category to it's parent category using ID's.
Right now I just have an sql query code that pulls all the "Categories"... how can I make it so that it will show a list of sub categories under each one?
<?php
$catlist= mysql_query('SELECT * FROM categories WHERE hide = 0 ORDER BY `order` ASC')
or die(mysql_error());
?>
<?php foreach ($catlist as $catitem): ?>
<h2 class="category"><?php echo $catitem['name']; ?></h2>
<?php endforeach; ?>
<?php ?>

this will get you the rest of the info - you will then need to do layout and suppress the repeating category text.
SELECT *
FROM categories c, sub_categories s
WHERE c.hide = 0
AND s.category_id = c.category_id
ORDER BY `order` ASC

You could use a join onto the subcategories table. http://dev.mysql.com/doc/refman/5.0/en/join.html
However, I recommend not differentiating between top level and sub-level categories at the table level, but rather put them all in one table with the following fields: parent_id, left_id, and right_id. Basically, this allows an unlimited depth of categories within a hierarchy. It may take a little research into how to properly implement it, but it is more powerful by far.

Related

PHP / MYSQL Do I Need to SQL Join?

I know this may be a stupid question but I am not very experienced with SQL Joins and I don't want to do it without fully knowing that it is the right thing to do.
I have created a recipe site which have different categories like bread, biscuits, cake etc. these are all in the category table of the database. I have recipes in the recipe table.
The problem I am facing is, on the category page, since each category has its own ID I created one page where each categories redirect to and used this code
<a href="index.php?p=selected&id=<?php echo $recipe['cat_id']; ?>">
This one page features different categories based on the ID, the id is changed in the url so for the bread category it would look like this:
index.php?p=selected&id=1
So, since there is one page for each category I want it to display the recipes, I used this code:
$query = "SELECT * FROM recipes ORDER BY recipe_id ASC";
but this displays every recipe in the database, what I want is for it to display the recipe based on the category it is in like below:
$query = "SELECT * FROM recipes WHERE cat_id = :id ORDER BY recipe_id ASC";
The cat_id is part of the category table, so do I need to join this table to the recipe table to make it work?
Be sure to tell me if I have missed something,
Thank you for your time.
yes you have missed something
must add column cat_id in recipes table which equal cat_id in category table
when you add item in recipes table
and then it simple
$query = "SELECT * FROM recipes
WHERE recipes.cat_id = :id";
or
$id = intval($_GET['id']);
$query = "SELECT * FROM recipes
WHERE recipes.cat_id = $id";
If one recipe one category then,
SELECT * FROM recipes inner join category
on category.id=recipe.cat_id
where cat_id = :id ORDER BY recipe_id ASC";
If one cateory many recipes then
SELECT * FROM recipes leftjoin category
on category.id=recipe.cat_id
where cat_id = :id ORDER BY recipe_id ASC";

SELECT DISTINCT multiple values from a single cell

Let's say I have the following table, called test:
Executing the query SELECT DISTINCT category FROM test ORDER BY category; will output:
When changing a value as follows:
…and calling the query SELECT DISTINCT category FROM test ORDER BY category; again, I'll get:
But I want to get the following instead:
Is there a way to do this in SQL? Or should I do this directly in my PHP?
You should have 3 tables here. One will hold the the categories, the other one will hold the items and the final one will hold the relations between categories and items (it is also known as associative table):
categories: id name
items: id name
categories_items: category_id item_id
Your query in this case will become:
SELECT id, name
FROM categories
ORDER BY name;
If you want to get all items from a category you could do:
SELECT id, name
FROM items
JOIN categories_items
ON items.id = categories_items.item_id
AND categories_items.category_id = 4;
You should definetely normalize your tables but if you still insist on this table structure, you can try this query:
WITH CatChar(aChar, remain) AS (
SELECT LEFT(category,1), RIGHT(category, LEN(category)-1)
FROM test WHERE LEN(category)>0
UNION ALL
SELECT LEFT(remain,1), RIGHT(remain, LEN(remain)-1) FROM CatChar
WHERE LEN(remain)>0
)
SELECT DISTINCT aChar FROM CatChar
(Assuming your all category names are just one char length, otherwise you should reorganeze LEFT(...) part to split according to your separator)

Display data as menu from 3 tables

I have 3 tables, categories with column names as id and cat_id. Cat_id=0 give me Veg and Cat_id=1 gives me Non veg.
Now i have another table menu(columns me_id,me_name and re_id) having main categories and item(columns item_id,re_id,me_id,cat_id,item_name and item_rate) having sub_ctegories
i want out put like as below
Veg Menu Non Veg Menu
Main_cat1 Main_cat2
--Sub_cat1 --Sub cat1
Main_cat3
--Sub_cat3
Please help
First of all i could not understand why you have kept cat_id in item table, secondly what is the purpose of re_id which is a foreign key in item table whereas you have already kept me_id as foreign key. Finally you need a foreign key in menu table. Some thing as cat_id.
Keeping that in mind your query will be like this
SELECT * FROM categories INNER JOIN menu ON categories.cat_id = menu.cat_id INNER JOIN item ON menu.me_id = item.me_id WHERE cat_id = 0;
You can change the cat_id to 1 here: WHERE cat_id = 1 by some form input, jquery or simply by assigning id and passing parameters via url (GET method).

display the subcategory data also on submit main category query in php

I have created a website where i have put category in three levels like
Main category -> sub category -> sub sub category
and this category i used in adding product whatever category i selected from the list each product have get in to that category. Now i am trying to display the products category wise on my site there i have put a list buttons where i have display all the category and sub categories now the problem is that when i m going to click on main category it displays only those products which are having that category selected but i want to display the subcategory also if a main category clicks, here is the query:
SELECT * FROM `products` WHERE `product_category`='$_REQUEST[cat]' ORDER BY `product_id` DESC
in this query the request cat is the name of the category which i got on page.
i want to know the query which display the sub category also if a main category is clicked
assuming you have some relations with product_category like parent_category
when main category is clicked id=1 you should also search for it's children
like you did:
main category
SELECT * FROM `products` WHERE `product_category`='$_REQUEST[cat]' ORDER BY `product_id` DESC
sub category
SELECT * FROM `products` WHERE `category_parent`='$_REQUEST[cat]' ORDER BY `product_id` DESC
also be aware of your $_REQUEST['cat'] as it's vulnerable and can be exploited. You should use mysql_real_escape_string() or maybe just (int) ($_REQUEST['cat'])
SELECT product_category, (SELECT category_name FROM category WHERE c_id = products.c_id) AS Category,
(SELECT sub_category_name FROM sub_category WHERE sub_cat_id = products.sub_cat_id) AS 'Sub Category'
(SELECT sub_sub_category_name FROM sub_sub_category WHERE sub_sub_cat_id = products.sub_sub_cat_id) AS 'Sub sub Category'
FROM `products` WHERE product_category='1'
store your sub categories and sub sub categories in other tables and in product table just store their id's and then utilize the above query for the product with cate name and sub name
and for sub categories of your relevant category you can select from sub cate table
SELECT * FROM subcategory where category_id='$_REQUEST[cat]'

Sorted output of a joined MySQL result in PHP

Doing an allnighter on a project and my mind is blank atm... Simple question really:
I have two MySQL tables, product and category. Each product belongs to exactly one category. Every category has several products.
SELECT
p.uid as product_uid, p.name_NL as product_name, p.price as product_price,
c.uid as category_uid, c.name_NL as category_name
FROM
product p, category c
WHERE
p.category_uid = c.uid
This gives me a nice overview of all products in their respective category. My question is about outputting this data on the page. I'm aiming for this:
<h1>Category name</h1>
<p>Product in this category</p>
<p>Other product in this category</p>
<h1>Next category</h1>
<p>Product in next category</p>
My mind is completely blank right now. How would one go about doing this?
I would like to avoid doing subqueries (if possible).
Kind regards,
M
What about adding ORDER BY category_uid so that the products are ordered by category in your SQL query. Then using PHP, loop through each product (row) and when you encounter a new category, add a new header.
Example:
<?php
// ...
$previous_category_uid = null;
// Loop through each row.
while ( $row = $result->fetch_assoc() )
{
// If the category UID is not the same as the one from the previous row, add a header.
if ( $previous_category_uid != $row['category_uid'] )
{
echo '<h1>' . $row['category_name'] . '</h1>';
$previous_category_uid = $row['category_uid'];
}
}
The benefit of this method is that you don't have to nest queries. A single query will suffice.
Don't you just need to use a GROUP BY category_uid ?
Generally speaking you have two options:
Get all the data at once (like you are doing currently) then use PHP to either pre-sort the data by category. Then do your output looping over this array. So 1 query, 2 + n loops (where n is the number of categories).
Get all your categories and then loop over those for output. In each iteration you will need to query all products for that loop. So 1 + n queries, 1 + n loops (where, again, n is the number of categories).
Option 2 might be more straightforward, but clearly there are more queries. In the end, it's your call.
Assuming you're looking for alphabetical ordering for category names and products within each category:
SELECT
p.uid as product_uid, p.name_NL as product_name, p.price as product_price,
c.uid as category_uid, c.name_NL as category_name
FROM product p INNER JOIN category c ON p.category_uid = c.uid
ORDER BY category_name, product_name
This also converts your query's Cartesian product and WHERE to an inner join.
To output with the headers you want, just loop over the returned rows, and keep track of the category you're in. Whenever the category of the current row is different from the previous one, you print a new h1 for the new category and update the stored "current" category.

Categories