Is there a better way to design an E-commerce products database when the products can have multiple price lines? - postgresql

I'm trying to develop a new products database for a client and I am having a hard time finding a solution to handle the many different prices a product can have.
Variables that can affect the price of a product:
region (where the customer lives).
customer type (whether they're a new customer or a registered customer).
order type (whether you want to purchase the item once or subscribe monthly).
store type (there were many store types, but now they're transitioning to one, but I don't know if they will add more in the future again so I want this to be flexible
Product Table
id
product_name
sku
description
1
Vanilla Protein Powder
1111
This is a description...
Attributes Table
id
associate_type
region
store
currency_code
order_type
1
2
1
11
usd
1
2
2
1
11
usd
2
Product Attributes Table
id
price
product_id
attribute_id
1
49.95
1
1
2
29.95
1
2
I was initially thinking this would be a good route to go, but the issue that arises is on the product page I want to display the price of the product if you want to purchase it once and the price if you wanted to subscribe. The same issue would happen if I also wanted to show a list of product cards on a product category page displaying both prices.
The issue I run into
When I write a query to get the correct products with the correct price lines, I would filter all the products by the variables mentioned above, but I will always want the subscription price and the one-time price, so in the query, I would have to include WHERE order_type = 1 AND order_type = 2 but doing this would return duplicate records of the product/ products because of the different prices for a one-time purchase and a subscription purchase.
Is there a better way to set up the tables I have so that the query would not return duplicate records of the product/ products? Or is there a way to write the query to handle this for me? Or do I even need to switch up my database design altogether?

Related

Tableau report that aggregates the same row into multiple groups

A vendor has many products in various product categories. A new customer might buy items from one or multiple categories. The data rows represent one order/item combination, such that if three items are bought in an order, there will be three rows in the data set. When trying to answer the question of the average sales total by order category, I want to include each order total in every applicable category. For example, if this is what happened:
Customer #1: Bought $20 in category A and $40 in category B.
Customer #2: Bought $40 in category B.
Customer #3: Bought $40 in category A and $30 in category C.
The data will show:
Row 1: Customer #1 bought $20 in category A.
Row 2: Customer #1 bought $40 in category B.
Row 3: Customer #2 bought $40 in category B.
Row 4: Customer #3 bought $40 in category A.
Row 5: Customer #3 bought $30 in category C.
My report should show:
Category A: Two customers, $130 total (**Not $60**). Average sale per order = $65.
Category B: Two customers, $100 total. Average sale per order = $50.
Category C: One customer, $70 total. Average sale per order = $70.
Each order should get counted in its entirety in every applicable category. This means that a given row of data will get aggregated into multiple category groups. How can I do this in Tableau?
Sounds like a case for a Level of Detail calc! Fix to the Category...
{FIXED [Category] : SUM([Sales])/COUNT([Orders]) }
Be sure to check for division by zero.
UPDATE
In light of the new detail specifying that the data set is item level, not order level, you can count the distinct order numbers instead of counting the number of records.
{FIXED [Category] : SUM([Sales])/COUNTD([Order Number]) }

Segregate Products based on shipping <SQL>

I have 10 different products (A,B,C),..,J)have multiple purchase dates (by various customers) and delivery dates. I want to see which products have the date difference of less than 5 days. If the date difference is less than 5 days, which products have customer rating less more than 3.If the above criteria is satisfied I want to fetch those products that has the minimum date difference from the queue along with the "Important_date".If there are same minimum date difference for a particular product then I would like to select the top one among the same product in recent times and mark the purchase date as the "Important_date".
The columns in the table are: Product,Purchasedate,deliverydate,date_difference,customer_rating.
I am trying to use case statements to solve the problem in PostgreSQL.
I am looking for an output which will give me all the columns of the table along with "Important_date."

Show the same field twice, side by side, with different values

How can I want print the same field twice with different value for each?
My Product and Shop tables are linked with product_id as the primary/foreign key.
Product
product_id
product_name
Shop
shop_id
product_id
quantity_product
When I use Expert Selection, I take all products on Shop_id 1 and Shop_id 2 (if Shop_id is in {1,2}...). Now I want to print 2 different quantity_product fields from Shop 1 and Shop 2 in the same line as my product_id. Something like:
product_name quantity_product(shop_id: 1) quantity_product(shop_id: 2)
1 10 20
I tried adding a new link in my database scheme with another Shop table, but it didn't work out.
You can set up a CrossTab in the summary section to handle any number of Shops. (So long as there's room on the report for all the shop columns)
If that doesn't work you can manually set up a summary for each Shop:
Keep in mind both of these solutions will need to be placed in a Footer section instead of the Details.

Design Database schema for billing system

I want to design a database for billing system. In one bill a customer might have purchased multiple different items ,for example fot bill Id 1 customer purchased 2 apples 3 bananas and 1 watermelon. i want to know how i can normalize this database.
This is a pretty standard, basic normalization exercise with a pretty standard solution. The usual approach is to have an orders table containing order ID, customer ID, order date &c., and an order_items table with a record for each line item on the order.

Access Crosstab or Form based on 2 tables with dates

There are a few answers here already that have part answered my challenge in Access but not fully.
I have 2 tables that form the basis of my database: customers and items
I have a further 2 tables; one for order quantities against customers and items (orders_a), and one for forecast quantities against customers and items (forecast_a).
forecast_a and orders_a also have a date for each customer and item combination (basically there will be 12 dates only for the 12 months of the year - 01/01/12,01/02/12,01/03/12 etc.)
Because a user will want to manually forecast quantities for a full year for each customer and each item, if there were 2 customers and 2 items, the forecast_a table would contain 48 rows. 2 items x 2 customers = 4, 4 x 12 dates = 48. The same goes for the orders_a.
I know this is a slightly unusual set up but the user requires visibility of a full year.
My main challenge based on this is as follows:
A user will want to see a form with customers in the first column, items in the second and then (like a crosstab): Jan Forecast Qty, Jan Order Qty, Feb Forecast Qty, Feb Order Qty etc.
Therefore how would I create a crosstab to pull both these tables together, and how would I go about creating a form for data entry off the back of it?
I may well be constructing my database the wrong way but the fact that the user needs a 'grid' where every entry is manual means I can't just have a form that creates a record one at a time for orders or forecasts.
Thanks in advance!
Nick
The problem you have is that this is a task that is in essence a spreadsheet task. Accordingly it may be best handled in Excel. To achieve this create an Excel object, create a blank worksheet, populate it with the data, then have a button to suck it back into the database when the user has finished.