How could I create a list in php of categories and types of topics that are mixed together?
Meaning, the list should look like this:
Sports (this is a category)
Soccer (this is a type)
Golf (this is a type)
Basketball (this is a type)
Science (this is a category)
Biology (this is a type)
Chemistry (this is a type)
Anatomy (this is a type)
The difficult part is that sports and science come from the same table (called categories), and soccer, golf, basketball, biology, chemistry and anatomy all come from a different table (called types). In the MySQL table "types" there is a foreign key that points to the id of the entry in the categories table. The current setup in MySQL cannot easily be changed as the navigation of the site is dependent on it.
How could i use php to put the types in between the categories?
Currently the code i have is this:
<?php session_start ();
include 'connect.php';
$result = mysql_query("SELECT * FROM categories JOIN types ON categories.catid = types.typecat");
while($row = mysql_fetch_array($result))
{
echo $row["catname"];
}
?>
However, that outputs "SportsSportsSportsSportsSportsScienceScienceScience," which it obviously shouldnt. There are 5 types in sports, and 3 in science. So i am not sure what is happening there and i cant proceed on to the next step of adding in php to include the types.
I think you need two lists with main category and sub-category, if so you can do as follows
fetch categories from db and display in list 1 with sub category list empty
on change of category submit the form using jquery or javascript
based on category posted fetch sub-categories from database and display in list 2 and select attribute of list 1 make it as selected based on posted category value.
You can use ajax too instead of submitting form.
I believe you have an id_cat in your types table.
Then you should use SQL JOINs.
I don't have the code for you, but the query would be either:
select category, type from categories c, types t on c.id = t.id group by category;
or:
select distinct category from categories;
Then query each category individually.
I suspect the single query would be more efficient.
Related
I have 3 Tables. model, category, and document. Documents belong in a category, which belongs to a model, and models can have multiple categories, which can have multiple documents.
I'm trying to build & execute this query in PHP, assigning each document a randomly selected category from a list of the categories in the currently selected model.
So, if a model has 10 categories (cat1-cat10), with each of those categories having 10 documents, the end result would make 1000 documents have a random_category_id field of cat1 - cat10 assigned at random, but not overwriting the existing category_id of the document.
Later in the application, I need to be able to calculate when document.category_id == document.random_category_id.
Is there a way to do this in one query. I'm new to SQL & PHP (and haven't mastered any kind of JOIN yet), so please forgive the blunders in database design & mixed coding approaches. I know the below example will not execute.
I'm using MySQL 5.5.28 with InnoDB.
Pseudocode Example
$catList = SELECT category_id FROM category WHERE model_id = '$current_model_id'
UPDATE document.random_category_id = RANDOM($catList) WHERE document.model_id = '$current_model_id'
Thank you!
Background:
I am creating a three tier e commerce website which sells books. Within my website I have created a form (only accessible to staff members) which allows the staff member to add a new book to the system (the database).
At the moment I have a table within my database which records the following data:
book_isdn // unique identifier of each book.
book_cat
book_title
book_author
etc..
Along with this, I have created a table for book categories which stores the following:
cat_id
cat_title
I have defined the following rows in the categories table:
cat_id 1 = Business books
cat_id 2 = Computing books
cat_id 3 = Science books
cat_id 4 = History books
etc
The problem:
In the form which allows a staff member to add a new book, I have a list:
<select multiple name="b_category" style = "width:150px" required>
<?php
$get_cats = "select * from categories";
$run_cats = mysqli_query($connect, $get_cats);
while ($row_cats = mysqli_fetch_array($run_cats)) {
$cat_id = $row_cats['cat_id'];
$cat_title = $row_cats['cat_title'];
echo "<option value='$cat_id'> $cat_title </option>";
}
?>
</select>
I want to add a new book to the 'books' table with the corresponding cat_id for the category to which the book belongs to (i.e. business, computing etc.).
However, a book can also be in two categories, i.e. a book can be both in the field of business and computing.
The question:
How can I alter the form so that it selects multiple options from and adds them to the database, along with the cat_id?
For example:
if using the form I complete all other fields and select computing and business from the list, I want it so that upon clicking "Add new book", the form data is sent to the 'books' table where I will be able to see the new book and under the field of book_cat, I will see 1,2.
I am completely stumped. Is there any way to approach this issue? I hope I have explained this well.
Thanks.
Ok, let's start with something you have not asked for.
a) DB design
Please do not store a concatenated id value like 1,2 in book_cat.
That makes lookups and search hard, because you need to fetch & split every single time. That might only work for really small systems.
What you are looking for is a relation table from books to categories.
Name it like this books_to_categories, with book_id and cat_id.
Query: SELECT cat_id FROM books_to_categories WHERE book_id = 2;
Result: array one or more ids, then resolve the cat_id to it's name (cat_title) via the category table.
The keyword here is database normalization.
b) Formular
Ok, you have a drop down list box, where you can do multiple selections.
Now, the values of these selections need to be transfered to the server side.
One trick is to use array syntax, instead of
<select name="b_category" size=4 multiple>
just use
<select name="b_category[]" size=4 multiple>
and on the server-side var_dump($_POST['b_category']); to see the values received. Then simply iterate over the values of the array and make your database entries.
I want to store reviews in a flexible system of categories and subcategories, and am currently in the process of designing the database structure for that. I have an idea how to do that, but I'm not entirely sure if it couldn't be done more elegant and/or efficient. These are my thoughts - if anybody can comment on if/how this can be improved I'd be really grateful.
(To keep this post concise, I only list the important field for the tables)
1.) The reviews are stored in the table "reviews". It has the following fields:
id: uniquite ID, auto-incrementing.
title: the title that will show up in <head><title>, etc.
stub: a version of the title without spaces, special chars, etc. so it can be part of the URL/URI
text: the actual content
2.) All categories are in the same table "categories"
id: unique ID, auto-incrementing.
title: the full title/name of the categorie how it will be output on the website
stub: version of the title that will be shown in the URL/URI.
parent_id: if this is a subcategory, here is the categories.id of the parent category. Else this is 0.
order_number: simple number to order the categories by (for display in the navigation menu)
3.) Now I need an indicator which reviews are in what categories. The can be in multiple. My first idea was to add a "review_list" field to the categories and have it contain all reviews.id's that should be in this category. However I think that adding and removing reviews from categories would be a hassle and "unelegant". So my current idea is to have a table "review_in_category" and have an entry for every review-category relation. The structure is:
id: Unique ID, auto-increment.
review_id: the reviews.id
category_id: the categories.id
So if a review is in 3 different categories it would result in 3 entries in the "review_in_category" table.
The idea is, that when a user opens www.mydomain.de/animation/sci-fi/ the wrapper script will break up the URL into its parts. If it finds more than one category with category.stub = "sci-fi", it will check which of those has a parent category with the stub "animation". Once the correct category is identified (most the time the stubs are unique anyway so this check can be skipped) I want to SELECT all review_id's from "review_in_category" where the category_id matches the the one determined by the wrapper script. All the review_id's are put into an array. A loop will iterate through this array and compose the SELECT statement for listing all review titles (and create links to them using the stub values) by "SELECT title, stub FROM reviews WHERE id=review_list[$counter]" and then add "OR id=review_list[$counter]" until the array is completely travelled.
SO my questions are:
- Is the method my creating a single SELECT statement with potentially a large number of "OR id=" parts an "elegent" and/or efficient way to handle this situation or are there better variants?
- Does using a "taxonomy"-style table (review_in_category) make sense or would it be better to store the "membership"/"relation" directly in the reviews or category tables?
- Any other thoughts... I just started to learn this stuff and appreciate any feedback.
Thank you
Your design looks sound.
To retrieve all reviews in a category, you should use a join:
SELECT reviews.title, reviews.stub FROM reviews, review_in_category WHERE reviews.id = review_in_category.review_id AND category_id = $category
I want to add categories to my website - but with more complex sorting.
Lets say I have article a. now, I want a to be under main category a, but also on category c thats its parent is b.
I thought of doing it like this:
An article would have a main category field, and also parent_ids
parent_ids would be every category this item is belong to.
my problem is: lets say i have: parent_ids: |1|5|2|7|.
now i am in category id - 7.
how would my select query look like?
select * from categories where parent_ids LIKE '%|7|%'
is it efficient? is there a better idea?
Never store multiple values in one column. All column values in a normalized database should be atomic (single-valued).
The relationship between articles and categories is many-to-many. That means you should have a separate table, such as article_category (article_id, category_id) containing one row for each category each article is in.
I'm looking for a solution to list and browse categories and subcategories and their records (classified ads), when you store category levels in separate tables. In the past I have worked with the adjacency model but I have to stick to this database setup now, and it is new to me. I'm using php and mysql.
The site is a classified ad site structured the common way: it has the main category list on its homepage, when you click one of the category links then only its subcategories are listed and the ads that belong to this category, and so on, at every level.
I'm a bit confused in the following areas:
How do you construct
the category links when browsing
categories in order for the script to know which table it should select categories from if I consider the below
mysql structure? Do I need separate
parameters at every category level I access
like e.g: "mysite.com/?cat2=4" when
accessing category "4" in the cat2
table and "mysite.com/?cat3=9" when
accessing category "9" in cat3 table
in order to identify category
levels? If separate parameter not
needed, then how can php and mysql
tell what table you have to select
the categories from?
And most
importantly in this case, what is
the best way to construct SEO
friendly links? And how will mysql know
which table to select categories
from? I would like to use the most
simplest solution that is possible
like:
mysite.com/electronics/television/sony.
As far as I know, I have to include
at least the cat_id
somewhere in the link... where do I put it? and do I have to include the number of level as well? To
complicate it more the category
names are in foreign language with
accented characters (though I
created a function that changes
accented characters into latin ones
on the fly when generating category
links) so I think it is best to
select them by their ids.
How is a sample mysql select looks
like that selects the child
categories of a certain category?
How can I construct breadcrumb
navigation?
MYSQL STRUCTURE:
Table "cat1" (main category):
cat1_id | cat1_name
Table "cat2" (subcategory):
cat2_id | cat1_id | cat2_name
Table "cat3" (subsubcategory):
cat3_id | cat2_id | cat3_name
Table "ads":
ad_id | cat1_id | cat2_id | cat3_id | ad_title | ad_description
Thanks and sorry for the long post.
My favourite pattern for category (and tag) URLs:
http://mysite.com/articles/brains+zombies+legs+frogs
The + symbol is nice for tags, and friendly to spiders (and SEO). Using the text of the categories is important for both spiders and humans as it's meaningful.
As for the SQL, I suggest 2 tables for anything with categories or tags:
Categories (id, name, description)
CategoryRelationships (catID, thingID)
For any given thing, you join Categories to Things via CategoryRelationships. For example:
SELECT * FROM Things t
JOIN CategoryRelationships ON thingID = t.ID
JOIN Categories c ON catID = c.CatID
The result will be a list of Things and their categories, where you have only one definition of each category, and a bunch of links to the categories via the Relationship table.
As for breadcrumbs, they're a slightly different problem. Breadcrumbs either:
Provide navigation through your site hierarchy, or
Help the user retrace their steps
Depending on the type of breadcrumb you're aiming at, you take a different approach. For a simple site hierarchy set of breadcrumbs, you can simply parse the URL and foreach over the set of segments:
http://mysite.com/people/zombies/brains/brains
Parsing the URI would result in:
people, zombies, brains, brains
For which you would generate links to each segment.