I have two tables namely 'categories' & 'products' as follows:
categories
id | name
products
id | cat_id | name
cat_id in products references the categories table.
Now, I want to display the list of all products on a page, which will have to also display the name of the category the product belongs to(not the cat_id).
I am very new in PHP, so am doing the following way:
foreach($products as $product):
echo $product->id . $product->name;
echo getCategoryName($product->cat_id);
endforeach;
Its obvious that the database call to retrieve the corresponding category name is equal to the number of products to be displayed, and something tells me this is not good at all.
So, is there a better way to do the above? maybe by using SQL JOIN?
You should use SQL join, which is by far the best and easiest way to select data from two tables.
SELECT
p.id AS id, c.name AS category, p.name AS name
FROM
products AS p LEFT JOIN categories AS c ON p.cat_id = c.id
You can also use the statement by Trevor, but that's a different type of join. Both will work in this case, as long as the product ID always exist.
Update: A little update on LEFT JOIN and RIGHT JOIN. When you select from 2 tables, you have a left and right table (products is left here, categories is right). The query I gave you will match all products even if the category does not exist. A RIGHT JOIN would match all categories even if there are no products in that category.
Yeah, you'll need a sql join. Something like this:
categories id | name
products id | cat_id | name
select categories.name, products.id, products.name
from categories, products
where categories.id = products.cat_id
Related
I have a task to get products info like top sales, date, and brands. However there is no field Brands in a product table. What I have is two separate tables for products and brands, in addition I have another product_sales table which is basically the main table for products sales but the main table doesn't know anything about brands.
I suppose I have to join somehow the two basic tables and then link them by product id to the main table.
For now, I believe I have to work with the two tables containing info about the brand.
Brands has {id, brandId, brandname, total }
BrandsProducts has {id, brandid, productId }
My query:
SELECT
b.brandid,
b.brandname,
p.productid
FROM pgcdonbrands b, pgcdonbrandsproducts p
WHERE b.brandid = p.brandid
This I believe returns the correct result, Brand name and Id, and which Product Id is related to that brand. My question is now, how do I go on about including this in my main query for Product Sales table. The end result should be Product Name and Brand Name.
Something like this. As per your data you'll decide JOIN TYPE (LEFT/INNER).
SELECT *
FROM productSales ps
INNER JOIN (SELECT b.brandid,
b.brandname,
p.productid
FROM pgcdonbrands b
INNER JOIN pgcdonbrandsproducts p
ON b.brandid = p.brandid) t
ON ps.productid = t.productid;
SELECT ...
FROM BrandsProducts
INNER JOIN Brands ON BrandsProducts.brandid = BrandsProducts.brandid
WHERE ...
By joining your tables like this, you can use them as one virtual table
I am building a small online shop where I have a parent table called 'products' and a child table called 'images'.
I have followed best practice and set up a foreign key constraint with the field product_id establishing a link between both tables.
products
product_id (PK parent table)
product_title
product_category_id
product-price
product_quantity
product_description
long_description
product_image
images
image_id (PK for child table)
product_id (foreign key)
product_image_two
NB: Each product will have 2 images, thus I want to retrieve a product based on its product_id and get the associated images from each table.
ie. the query pulls product_image from 'products' and product_image_two from 'images'
I have trawled through a multitude of posts on here about JOIN and tried to refactor other folks code so far without success.
My Current Statement
<?php
$query = query("SELECT p.* , i.* FROM products p,images i WHERE p.product_id=i.product_id");
confirm($query);
while ($row = fetch_array($query)):
?>
It sounds like what you want is a LEFT JOIN. Using a LEFT JOIN, you can select everything in the product table but only rows from the images table if their corresponding key is present in the products table. So for example, your query could look like:
SELECT p.* , i.*
FROM products p,
LEFT JOIN images i ON
p.product_id = i.product_id
This will return every row in the products table, and a value of null for each column in the images table if no second image exists. Here is a simplified demo of what this does: SQL Fiddle
Try with inner join: according to your explanation it should work
SELECT p.product_id,p.product_image, i.product_image_two FROM products p
inner join images i on
p.product_id=i.product_id
I was working on SQL query to export Product Names, Id and respective category name to which the product belongs and a number of other few attributes present in product flat table.
In database, table names are:
`catalog_product_flat_1`,
`catalog_category_product` and
`catalog_category_flat_store_1`
I made this query:
select pr.entity_id as product_id
, pr.name as product_name
, catn.name as category_name
from catalog_product_flat_1 as pr
left
join catalog_category_product as cat
on pr.entity_id = cat.product_id
left
join catalog_category_flat_store_1 as catn
on catn.entity_id = cat.category_id
order by pr.entity_id ASC;
which serves the purpose for now. But can this be improved? The reason I am concerned with speed complexity is because this store has 440k products
I came across another solution on stackoverflow which used Main tables instead of flat tables. But had 4 left joins. Which one would be faster? Am I completely doing it wrong? Please don't mark this as duplicate.
Here is mysql Query to Fetch All products with their categories by sub-query
SELECT
e.entity_id AS product_id
, e.type_id AS product_type
, e.sku,
(
SELECT
GROUP_CONCAT(DISTINCT(cv.value))
FROM
catalog_category_entity_varchar AS cv, catalog_category_product AS at_category_id
WHERE
at_category_id.category_id = cv.entity_id
AND (at_category_id.product_id = e.entity_id)
AND cv.attribute_id = 41 and cv.store_id = 0
) AS category_name
FROM catalog_product_entity AS e;
We can achieve by this query also and I think its optimize also.
I am trying to have a section in a shop I am creating to display 5 random products, from that Category ID.
Firstly every category has an ID, and a set of Sub Catrgories, every Sub Cat has an ID, and within every Sub Cat is a number of products. Every Product also has an ID.
The Products table contains the ProductID and the SubCatID.
The SubCat Table Contains the SubCatID and The CatID
The Cat table contains only the CatID.
SO I need to display 5 random products by the CatID. I can get random products using a query similar to this:
$randomprod = mssql_query("SELECT TOP 5* FROM Products WHERE SubCatID = '1' ORDER BY NEWID()");
while ($echorand = mssql_fetch_array($randomprod)) {
I need a way to join the tables so I can display all products under a certain CatID however, and am finding it difficult because my Products table doesn't contain a CatID. I am aware there are a number of joins, but am fairly new to PHP and even newer to MS SQL. Can anyone tell me what join is best, or point me in the correct direction please?
Join products to sub categories, join sub categories to categories, like this:
SELECT TOP 5 Products.Name, SubCatergory.Name, Category.Name
FROM Products
INNER JOIN SubCatergory ON Products.SubCatID = SubCatergory.SubCatID
INNER JOIN Catergory ON SubCatergory.CatID = Category.CatID
WHERE Category.CatID = 1
ORDER BY NEWID()
I have used INNER JOIN in the above example.
I have a table for posts and a table for categories, what i want is to select posts that are in a specific category. The problem is that the category is stored in another table and not in the posts table, here is the example:
posts
id title body
---------------------------
125 Some title Blah blah
categories
postid category
----------------
125 politic
I want in single query to fetch posts in the politic category by example, what to do?
Use:
SELECT p.id,
p.title,
p.body
FROM POSTS p
JOIN CATEGORIES c ON c.postid = p.id
WHERE c.category = 'politic'
The issue I have with your CATEGORIES table is that storing the category value as a string means the data isn't normalized - you should instead have a CATEGORY table:
CATEGORY
category_id (primary key, auto_increment)
category_description
...and use the category_id value in the CATEGORIES table:
CATEGORIES
category_id (primary key, foreign key to CATEGORY.category_id)
post_id (primary key, foreign key to POSTS.postid)
select p.*
from posts p
inner join categories c
on p.id = c.postid
where
c.category = 'politic'
You need to join the two tables in your query
SELECT *
FROM posts P
INNER JOIN categories C on C.post_id = P.id
WHERE C.category = 'politic'
You can intuitively (this is NOT exactly a technically correct explanation) think of this join as appending the category field to a row in posts with the shared id (this is the 'on C.post_id = P.id'). The WHERE clause indicates that you want only those rows where category is 'politic'.
Inner join is one of several join types. Left join in particularly is another common one, and its difference in this situation is that rows of post without a match in categories would still be listed, but with nulls for the fields from categories. (With inner join such rows would not remain)
http://en.wikipedia.org/wiki/Join_%28SQL%29