Suppose I a table like this:
Categories:
| cat_id | cat_name |
|--------|----------|
| 1 | tvs |
| 2 | phones |
| 3 | tablets |
And then I have:
Products:
| product_id | product_name | product_category |
|------------|-----------------|------------------|
| 1 | tv sony | 1 |
| 2 | tv samsung | 1 |
| 3 | phone htc | 2 |
| 4 | phone motorolla | 2 |
| 5 | tablet apple | 3 |
And someone goes into index.php where I get 10 random products from the DB. For creating the link I'd have to fetch the database again (to get the name of the category) and then I could do something like mysite.com/phones/4 (that would be the link to phone motorolla).
Of course 10 wouldn't be too hard on the server but it's still another fetch on the database.
The other option is to fetch for the category name during the product creation, and generate a link there, something like:
| product_id | product_name | product_category | product_link |
|------------|-----------------|------------------|--------------|
| 1 | tv sony | 1 | tvs/1 |
| 2 | tv samsung | 1 | tvs/2 |
| 3 | phone htc | 2 | phones/3 |
| 4 | phone motorolla | 2 | phones/4 |
| 5 | tablet apple | 3 | tablets/5 |
However the name of the category may change and so the link wouldn't work anymore. So what should I do? Is there another way to do this?
Alright Nick so in SQL you have something very powerful called JOIN. A join in SQL allows you to merge columns from different tables based on a key. Usually the key is a primary key or a foreign key.
In your case, it seems you have as primary keys : cat_id and product_id
And as foreign key you have : product_category
Based on your database schema, you can query your tables like this :
SELECT p.product_id, p.product_name, c.cat_name
FROM PRODUCTS p INNER JOIN CATEGORIES c
ON p.product_category = c.cat_id
With this query you retrieve your product_id, product_name and cat_name based with only one query for your database.
Here is more info about joins in SQL => https://www.w3schools.com/sql/sql_join.asp
Hope it will help you.
Related
Basically I have 2 tables:
One contains all of the products, the other one contains all of the categories for the products.
For one category there may be more than one input field for the category. Few examples:
+-------------+--------+
| SKU | WV2323 |
| Name | DVD |
| Price | 2.00 |
| >(category) | dvd |
| memory | 700MB |
+-------------+--------+
+-------------+-----------+
| SKU | bla3434 |
| Name | Chair |
| Price | 50.00 |
| >(category) | furniture |
| height | 70cm |
| width | 50cm |
| length | 100cm |
+-------------+-----------+
All the values for the categories are in the categories table, connected to product via product_id. So if there are 3 fields for the product category, they are contained as 3 different rows connected to the same product id. I need to fetch all of these rows as one, so that I could pass the multiple values for the category at the same time. Is this possible to do via SQL query?
I have a small database:
+-----------+-----------+------------------------+
| Name | Number | Hobby |
+-----------+-----------+------------------------+
| Alex | 2, 3 | Game, Shopping |
+-----------+------------------------------------+
It's mean Number 2 is Game and Number 3 is Shopping.
How can I show above data like this table
+-----------+-----------+
| 2 | Game |
+-----------+-----------+
| 3 | Shopping |
+-----------+------------
Your database is not normalized. You need a third table that will be what's usually called a join table.
The people table. The primary key is id
+-----------+-----------+
| Id | Name |
+-----------+-----------+
| 1 | Alex |
| 2 | Thor |
| 3 | Iron Man |
| 4 | Dr Stange |
| 5 | Thanos |
+-----------+------------
The hobbies Table
+-----------+-----------+
| Id | Name |
+-----------+-----------+
| 1 | Game |
| 2 | Shopping |
| 3 | Fighting |
+-----------+-----------+
Join table called (for example) people_hobbies
+-----------+-----------+
| person_id | hobby_id |
+-----------+-----------+
| 1 | 1 |
| 1 | 2 |
+-----------+-----------+
This people_hobbies table will use person_id and hobby_id to create a multi field primary key. This will ensure that you will not be able to add the same combination twice... which should not even make sense.
person_id is a foreign key that references the id from the people table.
hobby_id is a foreign key that references the id from the hobbies table.
Having foreign keys will let you avoid having a key in the people_hobbies table that do not exist in both the people and the hobbies table.
The example in the table below shows that the person id 1 has two hobbies (1 and 2). For a human, that translates to Alex's hobbies are Game and Shopping.
The above structure will let you manage your DB the way most people do.
Just keep a few things in mind:
You cannot add anything in people_hobbies before they exist in both people and hobbies tables
You must have the CASCADE UPDATE and CASCADE DELETE to the foreign key definitions so that when you delete a person or a hobby from your tables, it will remove the relationship from the people_hobbies table.
SELECT * FROM ints;
+---+
| i |
+---+
| 0 |
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
+---+
SELECT * FROM bad_schema;
+------+--------+----------------+
| name | number | hobby |
+------+--------+----------------+
| Alex | 2, 3 | Game, Shopping |
+------+--------+----------------+
CREATE TABLE better_schema AS
SELECT DISTINCT name
, SUBSTRING_INDEX(SUBSTRING_INDEX(number,',',i+1),',',-1) + 0 number
, TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(hobby,',',i+1),',',-1)) hobby
FROM bad_schema
, ints;
SELECT * FROM better_schema;
+------+--------+----------+
| name | number | hobby |
+------+--------+----------+
| Alex | 2 | Game |
| Alex | 3 | Shopping |
+------+--------+----------+
I am doing a project in PHP, MySQL. I need to create a database in which there is a category to which there can be many subcategories ( like for a course book I can have physics, computer science, mathematics etc.).
Also there can be some categories which do not have subcategories (say Mythological Books).
The administrator has to add new category or subcategory via a form in PHP page which then updates the database.
How should I design the structure of my table where if admin for following two cases to be incorporated:
Admin only wants a subcategory to be added then upon selecting its parent category, it should be done.
Admin wants to add a new parent category and there exists no subcategory for it.
Please suggest how should I create my table(s).
Create a table called 'categories' with columns 'id', 'name', 'parent'.
Then use it like this:
1, Hardware, null
2, Storage, 1
3, Video, 1
4, Harddisks, 2
...
Here is a simple example with books:
Categories table:
+----+--------------------+--------+
| id | name | parent |
+----+--------------------+--------+
| 1 | Comics | NULL |
| 2 | Programming | NULL |
| 3 | SQL/PHP | 2 |
| 4 | Java | 2 |
| 5 | Marvel | 1 |
| 6 | Mythological Books | NULL |
+----+--------------------+--------+
Books table:
+----+---------------------------------------+----------+
| id | name | category |
+----+---------------------------------------+----------+
| 1 | PHP/MYSQL for dummies | 3 |
| 2 | Iron Man and the prisoners of azkaban | 5 |
+----+---------------------------------------+----------+
If you want to show all the books in the Programming>SQL/PHP category you just simply get them with a select query.
mysql> select * from books where category = 3;
+----+-----------------------+----------+
| id | name | category |
+----+-----------------------+----------+
| 1 | PHP/MYSQL for dummies | 3 |
+----+-----------------------+----------+
1 row in set (0,00 sec)
Category Table
+----+-----------------------+
| id | category_name |
+----+-----------------------+
| 1 | Buy Book |
| 2 | Buy other thinks |
+----+-----------------------+
Buy Table
+----+-----------------------+----------+-------------+----------+--------+-------+
| id | identity | name | description | per_rate | bought | costs |
+----+-----------------------+----------+-------------+----------+--------+-------+
| 1 | PROJECT[1]CATEGORY[1] | BOOK | PHP BOOK | 10 | 50 | 5000 |
| 2 | PROJECT[1]CATEGORY[1] | BOOK | PHP BOOK | 10 | 40 | 4000 |
| 3 | PROJECT[2]CATEGORY[1] | BOOK | JS BOOK | 2 | 50 | 100 |
+----+-----------------------+----------+-------------+----------+--------+-------+
I Want to Select category name from Other table when I select this table.
identity: PROJECT[project_id]CATEGORY[category_id]
So There are any way to pick the category id and select category name from other table
I Want Like This Table
+----+---------------+-----------------------+----------+-------------+----------+--------+-------+
| id | category_name | identity | name | description | per_rate | bought | costs |
+----+---------------+-----------------------+----------+-------------+----------+--------+-------+
| 1 | Buy Book | PROJECT[1]CATEGORY[1] | BOOK | PHP BOOK | 10 | 50 | 5000 |
| 2 | Buy Book | PROJECT[1]CATEGORY[1] | BOOK | PHP BOOK | 10 | 40 | 4000 |
| 3 | Buy Book | PROJECT[2]CATEGORY[1] | BOOK | JS BOOK | 2 | 50 | 100 |
+----+---------------+-----------------------+----------+-------------+----------+--------+-------+
You have a really bad data structure. The project and category should be in their own columns, with numbers stored properly as numbers, and proper foreign key relationships. In MySQL, doing this might require a trigger, but it is worth it.
Sometimes, we are stuck with other people's bad decisions. You can do what you want using like:
select b.*, c.category_name
from buy b join
category c
on b.identity like concat('%CATEGORY[', c.id, ']');
However, you should probably put effort into fixing the broken data structure.
(Sorry, my english isn't very good)
Hi, I am trying to learn how to work with junction tables in MySQL and I can't figure how to do something. I know the basics of MySQL but I have never worked with "JOIN".
In this test project, I would like to be able to show on a page the app of a given category (you click on "Games", only the apps that are in the "Games" category will be displayed on the page). I would like to know what the SQL request should look like.
Second question, let's say that an App could fit 2 different categories, how can I manage to give that app 2 different Category_ID in my database ?
Here is what my Database looks like at the moment :
Table name: APPS
+------------+-------------------+
| App_ID (pk)| App_Name |
+------------+-------------------+
| 1 | Weather Network |
| 2 | Is it sunny 2.0 |
| 3 | The Weather App |
| 4 | Zelda |
| 5 | Megaman |
| 6 | Doom 3 |
+------------+-------------------+
Table name : CATEGORY
+-----------------+-----------------+
| Category_ID (pk)| Category_Name |
+-----------------+-----------------+
| 1 | Games |
| 2 | Weather |
+-----------------+-----------------+
Table name : JUNCTION_APP_CATEGORY
+----------------+--------------------+
| APP_ID (pk) | Category_ID (pk) |
+----------------+--------------------+
| 1 | 2 |
| 2 | 2 |
| 3 | 2 |
| 4 | 1 |
| 5 | 1 |
| 6 | 1 |
+----------------+--------------------+
For your first question, the answer is
SELECT a.*, c.*
FROM APPS a, CATEGORY c, JUNCTION_APP_CATEGORY ac
WHERE a.App_ID=ac.APP_ID
AND c.Category_ID=ac.Category_ID
AND ac.Category_ID=<category_id for category "Games">
For your second question, you can use both APP_ID and Categor_ID as the primary key of table JUNCTION_APP_CATEGORY(note NOT TWO pks, but use the two columns together as ONE pk). So that you can put data like this:
+----------------+--------------------+
| APP_ID (pk) | Category_ID (pk) |
+----------------+--------------------+
| 1 | 1 | <-- APP_ID=1 belongs to both cat 1 & 2
| 1 | 2 |
| 2 | 2 |
| 3 | 2 |
| 4 | 1 |
| 5 | 1 |
| 6 | 1 |
+----------------+--------------------+