Relation among three tables: proper query and design suggestion - php

I have three tables (MySQL):
families where I define the products' families
products where I define the products
families_products where I relate families and products
------------------- -------------------- ------------------------
| familyID | code | | productID | code | | familyID | productID |
|----------|------| |-----------|------| |----------|-----------|
| 1 | p | | 1 | p3 | | 1 | 1 |
| 2 | a | | 2 | a5 | | 1 | 3 |
| 3 | e | | 3 | p1 | | 1 | 6 |
------------------- | 4 | e7 | | 2 | 2 |
| 5 | a2 | | 2 | 5 |
| 6 | p4 | | 3 | 4 |
-------------------- ------------------------
I have two questions:
Is this design convenient or is it better drop the families_products table putting the familyID relation directly into the table products?
With a design like this one, if I have the familyID how can I retrieve the products->code? I wrote this query but a query structure like this one would work if I drop the families_products table putting the familyID relation directly into the table products as said before, not in the case of a third relational table.
'SELECT productID, code, img
FROM products AS a
INNER JOIN families_products AS b
ON b.productID=a.productID
WHERE b.familyID=' . $families[$key]["familyID"]

Your data structure is fine.
If you have at most one familyID per product, then you should put the family in the products table. You should use the junction table (your structure) if a product can be part of multiple families.
As for your query, it is fine. I would use better table aliases:
SELECT p.productID, p.code, ??.img
FROM products p INNER JOIN
families_products fp
ON f.productID = fp.productID
WHERE fp.familyID = ' . $families[$key]["familyID"]

If your product only belongs to one product family you can skip the "familiy_product" table and add the familiy_id directly to the product. Only in case a product can be assigned to multipl families you need the "join" table.
With only two tables the SQL is quite easy:
select p.code from family f, product p where f.code ='xx' and p.family_id = f.id

Related

MySQL get Parent as Heading and children as items

Hello I have a database structure like this and some data in it
id | parent_id | name
1 | 0 | Nissan
2 | 1 | 240SX
3 | 1 | 350z
4 | 0 | Toyota
5 | 4 | Camry
6 | 4 | Prado
7 | 1 | Skyline
8 | 4 | Hilux
I want to take Nissan as heading and after show all the models. As well Toyota as heading and it's models below it. How do I achieve this using one query? Is it even possible?
You should normalize your database or at least separate your columns so there is a manufacturer column and a model column. This will then help you do a query such as
SELECT * FROM CARS WHERE manufacturer = 'Toyota';
or
SELECT * FROM CARS GROUP BY manufacturer;
But the best practise would be to have a table for storing manufacturers and a table for storing all models of the cars, then a table for storing your cars itself which will have 2 columns that are referenced from the other 2 tables.
So this will become:
id | parent_id | manufacturer_id | model_id
1 | 0 | 1 | 2 |
2 | 1 | 4 | 1 |
3 | 1 | 3 | 6 |
4 | 0 | 3 | 9 |
you will then do a query to join the 3 tables
SELECT cars.id, cars.parent_id, cars.manufacturer_id, cars.model_id, t1.manufacturer_name, t2.model_name from CARS
JOIN manufacturer_table t1
ON t1.manufacturer_id = cars.manufacturer_id
JOIN model_table t2
ON t2.model_id = cars.model_id
hope that helps
Try this, it should solve your problem:
SELECT
child.*
FROM
{your_table} parent
LEFT JOIN
{your_table} child ON child.parent_id = parent.id
OR (child.parent_id = 0 AND child.id = parent.id)
WHERE
parent.parent_id = 0
ORDER BY
parent.id, child.parent_id, child.name
{your_table} should be replaced in two places with your table's name (which you presented in the question).

Multiple joins in MySQL table

If I have one table that references the names of sponsors and the product ids of the products they recommend, as such:
--------------------------------
|Name |Product ID 1|Product ID 2|
--------------------------------
|Jon | 1 | 3 |
|Sally| 1 | 2 |
--------------------------------
And another table that lists the products:
----------------------------------------
|Product ID |Product Name|Product Price|
----------------------------------------
| 1 | Prod 1 | 25 |
| 2 | Prod 2 | 35 |
| 3 | Prod 3 | 45 |
----------------------------------------
How do I join these together so that I have the name of sponsor plus each product name and product price that they recommend? INNER JOIN and LEFT JOIN only seem to pull through one of the products, but not all of them.
Join twice.
SELECT s.name, p1.ProductName AS product_1_name, p1.ProductPrice AS product_1_price, p2.ProductName AS product_2_name, p2.ProductPrice AS product_2_price
FROM sponsers AS s
JOIN products AS p1 ON s.ProductID1 = p1.ProductID
JOIN products AS p2 ON s.ProductID2 = p2.ProductID

How to select values from two different tables in SQL

I have two tables in my SQL Server database. The first is catgeories and second is products. There is a column categories_id in both tables.
HERE IS MY TABLE FOR CATEGORIES :
+----+----------+----------+
| id | category | parent |
+----+----------+----------+
| 1 | BOY | 0 |
| 2 | GIRL | 0 |
| 3 | SHIRT | 1 |
| 4 | SKIRT | 2 |
| 5 | JACKET | 1 |
+----+----------+----------+
TABLE : PRODUCTS
+-------+--------------+----------------------+
| id | title |PRICE | Categories |
+-------+--------------+------+---------------+
| 1 | RED SHIRT | 300 | 3 |
| 2 | blue SKIRT | 500 | 4 |
| 3 | jeans jacket | 500 | 3 |
+-------+--------------+------+-----+---------+
Now I want to select the values from Products table for a particular category like BOY.
Try This:
SELECT pr.id,pr.title,pr.price from products AS pr
INNER JOIN CATEGORIES AS cat ON cat.id=pr.Categories
WHERE cat.category='Boy';
SELECT products.* FROM products INNER JOIN categories ON products.categories = categories.id WHERE categories.category LIKE '%BOY%';
Use this query..
Either
SELECT * FROM tproducts WHERE categories = 1
or
SELECT * FROM tproducts
JOIN tcategories ON tcategories.id = tproducts.categories WHERE tcategories.category = 'BOY'
I don't know your table names so I just used tproducts and tcategories
There is no boy(1) ID in Categories(field) in PRODUCTS(table)
SELECT * FROM CATEGORIES
INNER JOIN PRODUCTS
ON CATEGORIES.id=PRODUCTS.Categories
WHERE CATEGORIES.category ='BOY'
FOR this use join query Example:
select *(or you can get any column as you write name) from table1 join table2 on table1.id=table2.id where table1.category='BOY';

Select records without category in many to many relationship

I have a db with some products, they can be "tagged" with many categories. Some products have not an assigned category and I need to find them. Ineed to find records without category. I have created this tables:
ITEMS
+----+------+
| ID | Item |
+----+------+
| 1 | qwe |
| 2 | asw |
| 3 | wgr |
+----+------+
CATEGORIES
+----+----------+
| ID | Category |
+----+----------+
| 1 | xxx |
| 2 | yyy |
+----+----------+
RELATIONSHIP
+---------+--------+
| id_item | id_cat |
+---------+--------+
| 1 | 1 |
| 1 | 2 |
| 2 | 1 |
+---------+--------+
This is the (not working) query:
SELECT item.id COUNT(relationship.id_item) AS n
FROM item
JOIN relationships GROUP
BY relationships .n
WHERE item.id = relationships.id_item
AND relationships.n =0;
you can use subquery with NOT IN clause
SELECT i.id
FROM item i
WHERE i.id NOT IN ( SELECT r.id_item
FROM RELATIONSHIP r);
You want a left join and then find the ones that don't match:
SELECT i.id, COUNT(relationship.id_item) AS n
FROM item i LEFT OUTER JOIN
relationships r
on i.id = r.id_item
WHERE r.id_item is null;

Performing Searches over Many-to-Many Relationships

I have a database which (for the purposes of this example), has two tables that have a many to many association (with an intermediary table for holding the associations). Here is there structure:
Table A:
+-----+-------+-------+-------+
| aID | aCol1 | aCol2 | aCol3 |
+-----+-------+-------+-------+
| 1 | foo | aoo | doo |
+-----+-------+-------+-------+
| 2 | bar | aar | dar |
+-----+-------+-------+-------+
| 3 | baz | aaz | daz |
+-----+-------+-------+-------+
Table B:
+-----+-------+
| bID | bCol1 |
+-----+-------+
| 1 | alice |
+-----+-------+
| 2 | bob |
+-----+-------+
Association Table:
+-----+-----+
| aID | bID |
+-----+-----+
| 1 | 1 |
+-----+-----+
| 2 | 2 |
+-----+-----+
| 3 | 1 |
+-----+-----+
If I want to search for information by aCol2 LIKE 'aa%' AND the row has an association to bCol1 = 'bob' (i.e. resulting in only row aID = 2), how could I assemble a MySQL Query that could do something similar?
p.s. Sorry for the poor clarity, I am not exactly sure of the wording, but in a nut shell, it is about searching for data from one record that (for the purposes of this) has a 1-* relationship via a connecting table to a number of records, by information that exists in the entire set
SELECT
a.*
FROM
table_b b
INNER JOIN associations ab ON (b.b_id = ab.b_id)
INNER JOIN table_a a ON (ab.a_id = a.a_id)
WHERE
b.col_1 = 'bob'
AND a.col_2 LIKE 'aa%'
It's been awhile, but I believe this should work:
SELECT
*
FROM
A,
B,
associations
WHERE
A.aCol2 LIKE 'aa%' AND
A.aID = associations.aID AND
associations.bID = B.bID
You have to do 2 inner joins to combine the 3 tables.

Categories