PHP, MySQL E-Commerce Filtering Approach - php

I have a quick question in regards to the approach to displaying products on an e-commerce package I am putting together. The problem that I facing is that I would like visitors of the site narrow their search.
For example, a use case would be:
A Visitor is currently browsing a season of products (eg. Summer Collections)
He / She should then be able to filter by category and brand within that season, so for example they might decide that they only want to see Pants from Clothes Galore.
The problem, I ma facing is that doing a single SQL query in order to find products that match all three of these factors (so the product is in the summer collection, is a pair of pants and made by clothes galore). The thing that makes this overly difficult is that products can be in multiple categories and seasons. So there would need to be an insane amount joins in order to grab the right result.
My database structure is as follows:
product -> product_category <- category
product -> product_season <- season
product <- brand (a product can only be made by one brand)
Hope someone can share their wisdom on this...

If you have a big catalog, you might be better to use Apache Solr ( http://lucene.apache.org/solr/ ). Otherwise, there are a few approaches.
You don't need the overhead and straight SQL isn't that insane, will perform reasonably well:
SELECT product.*
FROM product
LEFT JOIN product_category
LEFT JOIN category
LEFT JOIN product_season
LEFT JOIN season
WHERE season = ? AND category = ?
Alternatively, If you don't like the number of rows returned, you can aggregate the category and season into the product table (new columns), then use like queries to find things:
SELECT product.*
FROM product
where product.categories like '% category %'
and product.seasons like '% season %'

Select product.* From product
Left Join product_category On (product.product_id = product_category.product_id)
Left Join product_season On (product.product_id= product_season.product_id)
Left Join brand On (product.product_id = brand.product_id)
Where product_category.category_id = '$catId'
And product_season.season_id = '$seasonId'
And brand.brand_id = '$brandId'
Order By product.product_name
Ok, this is assuming product, product_category, product_season, brand, season, category are all tables. You should pass in the ID's of the season and category table directly from whatever you are using to filter the search by so that you don't have to join these tables.

Related

PHP/MYSQL Join and distinct multiple tables and show results by 2 criteria

I have searched around for an issue like I have but I have not found anything :-( , so, I have decided to open a question. I'm working on a travel agency website and I'm stuck. I have 6 tables:
1. category
2. country
3. city
4. type
5. offer
6. price
Now, the relations of each one is like this: in offer table are recorded id's of category, country, city, type and, in price table is recorded offer id. In this way, via admin panel, the process starts by creating a new offer and after that, creating prices for that offer. This is way the offer id is recorded in price table and not inverse.
What I have right now is the following:
SELECT DISTINCT
price.prFood,
offer.*
FROM
category,
country,
city,
`type`,
price
INNER JOIN offer
ON price.prOfferID = offer.offerID
WHERE offerType = typeID
AND categoryID = offerCategory
AND countryID = offerCountry
AND prOfferID = offerID
AND offerActive = '1'
AND offerCity = cityID ;
This query shows correctly, only once, every offer that has a price but, what I need is to show also offers that are active and don't have a price. So, I need a little help on the correct query to show all offers that are active, have or don't have a price.
Use left join for your price table and move where condition in on clause. I have used aliases to give short names to table, so if I have not selected proper columns, please use right aliases for the columns.
SELECT DISTINCT
p.prFood,
o.*
FROM
offer o
LEFT JOIN price p ON o.offerID = p.prOfferID
INNER JOIN category ca ON o.offerCategory = ca.categoryID
INNER JOIN country c ON o.offerCountry = c.countryID
INNER JOIN city ci ON o.offerCity = ci.cityID
INNER JOIN `type` t ON o.offerType = t.typeID
AND o.offerActive = '1'

MySQL join returning redundant data

I am building an auction website. Right now, I am building the item description page, that has item details, as well as current bid history. My bids table has a FK of Item_id.
My current query looks something like this:
SELECT bids.Item_id, bids.User_email, bids.Bid_amount, products.*
FROM bids
INNER JOIN products
ON bids.Item_id=products.Item_id;
This returns all of the bid information I need - but also returns the item description for every bid row. I only need the product information once. Is it best to just use two queries on this?
Any help is appreciated
If you need the bids data separately from the products data, then you should use two queries.
One query cannot really be arrange to return different columns for different rows.
SELECT b.Item_id, b.User_email, b.Bid_amount, p.*
FROM bids b
INNER JOIN products p
ON b.Item_id=p.Item_id
WHERE p.Item_id=something;
This will not repeat products..

Joining three MS SQL Tables in PHP to display random products

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.

Slow query on ecommerce website (selecting products)

SELECT products.*
FROM products
LEFT JOIN product_category
ON products.id_product = product_category.id_produs
LEFT JOIN categories
ON product_category.id_category = categories.id_category
INNER JOIN options
ON products.id_product = options.id_product
WHERE categories.id_category = '472'
AND product_category.id_category = categories.id_category
LIMIT 0, 20
Hello, I'm working on a ecommerce website for a programming contest and I have some issues with the category page, where the products will be listed.
In MySQL there are 4 tables: products, categories, product_category (which contains the relation of category and products) and options. The options table contains various attributes for a product that you can choose to buy (like weight, height, color). I need to call these on the category page because there is a product filter, and when I chose color: red, it will show all the products with the attribute color: red.
If I have 10 000 rows in products table, and each product have 5 options, so the options table will have 50 000 rows, the problem is that the query will be very slow, and it will take more than 30 seconds to display the products.
I'm sure the problem is with the query, but I don't how to make it. What should I write in the query in order to get the products on the page in under 5 seconds?
Make sure that you have indexes on id_category and id_product for those tables, then stick EXPLAIN in front of it, and post the output, to be honest, if you don't have indexes, that might do the job anyway.
A few things: You're specifying this relationship twice:
AND product_category.id_category = categories.id_category
and
ON product_category.id_category = categories.id_category
This may be confusing your database optimizer.
Another potential optimization is to move the column you are doing your WHERE clause on up a table. Turn WHERE categories.id_category = '472' into product_category.id_category = '472'
` and it will reduce the number of records being joined in.
As mentioned in some of the questions, an EXPLAIN plan will show you what part of your query is slow, and give you an indication if there are indexes missing.

Retrieving and Displaying Categories and their children count

I am using PHP via Codeigniter for this scenario.
It's a basic category listing that has items assigned with to those categories. What I'm having problem with is showing the item count beside the category names on the category listing page.
How I was doing it was a very ineffective way i think, and I would really like to know what would be the common practice for this sort of thing.
So I was getting the category list in my controller, and then in my view, on the loop thru the categories, I call a model method to grab the count of the respective cat_id on every iteration. (horror!)
Should I be:
A) Getting the categories AND it's item count from 1 SQL statement
OR
B) Process the category list in the controller and get the categories' corresponding item counts in the controller
If so, how to ?
I would prefer to have one query with everything I need, if your DB design allow to do so.
Assuming you have a Categories table and a Products table you should be able to do something like this:
Select C.Category, Count(P.Id) as ProductsCount
From Categories C left join Products P on C.Id = P.Category_Id
Group by C.Category
Order by C.Category

Categories