Database schema for product prices which can change daily - sql-server

I am looking for suggestions to design a database schema based on following requirements.
Product can have variant
each variant can have different price
Price can be different for specific day of a week
Price can be different for a specific time of the day
all prices will have validity for specific dates only
Prices can be defined for peak, high or medium seasons
Suppliers offering any product can define their own prices and above rules still applies
what could be best possible schema where data is easy to retrieve without impacting performance?
Thanks in advance for your suggestions.
Regards
Harmeet

SO isn't really a forum for suggestions as much as answers. No answer anyone gives can be definitively correct. With that said, I would keep the tables as granular as possible to allow for easy changes across products.
In regards to #5, I would place start and end dates on products. If the price is no-longer valid, the product should no longer be available.
This includes relations for different seasonal prices, however you would either need to hardcode the seasons or create another table to define those.
For prices, if this is more than 1 region you may want a regions table in which case a currency column would be appropriate.
This is operational data, not temporal data. If you want it available for historical analysis of pricing you would need to create temporal tables as well.
Product Table
+-------------+-----------+------------------+----------------+
| ProductName | ProductID | ProductStartDate | ProductEndDate |
+-------------+-----------+------------------+----------------+
| Product1 | 1 | 01/01/2017 | 01/01/2018 |
| Product2 | 2 | 01/01/2017 | 01/01/2018 |
+-------------+-----------+------------------+----------------+
Variant Table
+-----------+-----------+-------------+---------------+-------------+-------------+
| ProductID | VariantID | VariantName | NormalPriceID | HighPriceID | PeakPriceID |
+-----------+-----------+-------------+---------------+-------------+-------------+
| 1 | 1 | Blue | 1 | 3 | 5 |
| 1 | 2 | Black | 2 | 4 | 5 |
+-----------+-----------+-------------+---------------+-------------+-------------+
Price Table
+---------+-----+-----+-----+-----+-----+-----+-----+
| PriceID | Mon | Tue | Wed | Thu | Fri | Sat | Sun |
+---------+-----+-----+-----+-----+-----+-----+-----+
| 1 | 30 | 30 | 30 | 30 | 35 | 35 | 35 |
| 2 | 35 | 35 | 35 | 35 | 40 | 40 | 40 |
| 3 | 33 | 33 | 33 | 33 | 39 | 39 | 39 |
| 4 | 38 | 38 | 38 | 38 | 44 | 44 | 44 |
| 5 | 40 | 40 | 40 | 40 | 50 | 50 | 50 |
+---------+-----+-----+-----+-----+-----+-----+-----+

Related

How to calculate a procentual difference between two columns in Data Studio pivot?

I have a data source table in Google Sheets, looking like:
+------------+--------------+--------+
| Date | Search query | Clicks |
+------------+--------------+--------+
| 09.11.2020 | keyword 1 | 20 |
+------------+--------------+--------+
| 16.11.2020 | keyword 1 | 24 |
+------------+--------------+--------+
| 16.11.2020 | keyword 2 | 23 |
+------------+--------------+--------+
| 09.11.2020 | keyword 2 | 18 |
+------------+--------------+--------+
| 09.11.2020 | keyword 3 | 19 |
+------------+--------------+--------+
| 16.11.2020 | keyword 3 | 17 |
+------------+--------------+--------+
With this data source i have a Data Studio pivot, looking like:
+--------------+------------+------------+
| Search query | 09.11.2020 | 16.11.2020 |
+--------------+------------+------------+
| keyword 1 | 20 | 24 |
+--------------+------------+------------+
| keyword 2 | 18 | 23 |
+--------------+------------+------------+
| keyword 3 | 19 | 17 |
+--------------+------------+------------+
How can i create an additional column in Data Studio with calculation of procentual clicks difference between dates? So the Data Studio table will look like:
+--------------+------------+------------+---------------------------------+-----------------------------+
| Search query | 09.11.2020 | 16.11.2020 | Difference between B and C in % | Formula for Difference in % |
+--------------+------------+------------+---------------------------------+-----------------------------+
| keyword 1 | 20 | 24 | 17 | =100-((B2*100)/C2) |
+--------------+------------+------------+---------------------------------+-----------------------------+
| keyword 2 | 18 | 23 | 22 | =100-((B3*100)/C3) |
+--------------+------------+------------+---------------------------------+-----------------------------+
| keyword 3 | 19 | 17 | -12 | =100-((B4*100)/C4) |
+--------------+------------+------------+---------------------------------+-----------------------------+
Last column contains just formula example.
I tried all available possibilities in Data Studio, but failed. The cause of my fail is maybe a bug i've experienced.
My other try was to build a pivot in Google Sheet directly and calculate the difference there - but this doesn't work for me too - because my Google Sheet breaks pivot when it renews its data.
The key is calculated field. For each pair of columns, where you need a difference, you create a calculated field. Then you add this field to your table and see the calculated difference. Like on the following screenshot.

data matrix html table from flattened data in Vue

I'm using Vue. Lets say I have a database table with the historical price of a few kinds of fruits for the last few years, so: fruit, year and price columns.
| fruit | year | price |
|--------|------|-------|
| apple | 2018 | 52 |
| apple | 2019 | 57 |
| apple | 2020 | 56 |
| apple | 2021 | 50 |
| banana | 2018 | 25 |
| banana | 2019 | 26 |
| banana | 2021 | 28 |
| pear | 2018 | 61 |
| pear | 2019 | 65 |
| pear | 2020 | 67 |
| pear | 2021 | 64 |
Now I want to create a html table which has fruit names on one axis and years on the other, and the cells contain the price for the given fruit / year combination as below. Some combinations might be missing from the data.
What features and template syntax you'd use? Please do not suggest tranforming the raw data: it comes straight from a database and there will be many tables like this, and I need a generic solution.
| | 2018 | 2019 | 2020 | 2021 |
|--------|------|------|------|------|
| apple | 52 | 57 | 56 | 50 |
| banana | 25 | 26 | n/a | 28 |
| pear | 61 | 65 | 67 | 64 |
I'm looking for elegant "vue-like" solutions. For now I created getRows(), getColumns() functions which collect all possible row and column values and then a getCell(col, row) function to pick up the right value from the dataset - but this might force Vue to rebuild the display more than optimal times when I edit the underlying data.
The broader question is how you work with relational data in Vue, because this is just the basic example, normally the name of the fruit would come from another base table...

Can a Database column have duplicate foreign keys?

I'm building an app for trading cards for a given game. This means, a user can have multiple cards and even repeated cards. This is may approach but I don't know if it's correct (or even possible):
Users
---------------------------
|id| name | cards_ids |
---------------------------
|20| John | 31, 40, 50, 50|
---------------------------
Cards
-------------------------------
|id| name | type |
-------------------------------
|31| Monster31 | Aqua Monster|
-------------------------------
|50| Monster50 | Rock Monster|
-------------------------------
|40| Monster40 | Air Monster |
-------------------------------
As you can see, a user can have many cards even if they are the same. Would this duplicate foreign keys approach work fine? I will do this using Postgres, if that's relevant
You need think third normal form when designing your database.
In this case you want add the number of cards as a property
Users
-----------
|id| name |
-----------
|20| John |
-----------
CardsOwned
--------------------------------
|user_id| card_type_id | count |
--------------------------------
|20 | 31 | 1 |
|20 | 40 | 1 |
|20 | 50 | 2 |
--------------------------------
Or even better they should have their own id. Even when two cards are the same monster, they can have different attributes like "Near Mint" or "Mint"
Your cards definition should be something like cards_type where you define the card. But the cards own by anyone are the cards where even when are the same cards they have different id because are two different cards
------------------------------------------
| card_id | card_type_id | condition |
------------------------------------------
| 1 | 31 | Mint |
| 2 | 40 | Near Mint |
| 3 | 50 | Used |
| 4 | 50 | Mint |
------------------------------------------
then you need the ownership table to control who own what
CardsOwned:
| card_id | owner_id |
| 1 | 20 |
| 2 | 20 |
| 3 | 20 |
| 4 | 20 |

SQL Database Constraint | Multi-table Constraint

I need to make 2 database constraints that connect two different tables at one time.
1. The total score of the four quarters equals the total score of the game the quarters belong to.
2. The total point of all the players equals to the score of the game of that team.
Here is what my tables look like.
quarter table
+------+--------+--------+--------+
| gNum | Period | hScore | aScore |
+------+--------+--------+--------+
| 1 | 1 | 13 | 18 |
| 1 | 2 | 12 | 19 |
| 1 | 3 | 23 | 31 |
| 1 | 4 | 32 | 18 |
| | | Total | Total |
| | | 80 | 86 |
+------+--------+--------+--------+
Game Table
+-----+--------+--------+--------+
| gID | hScore | lScore | tScore |
+-----+--------+--------+--------+
| 1 | 86 | 80 | 166 |
+-----+--------+--------+--------+
Player Table
+-----+------+--------+--------+
| pID | gNum | Period | Points |
+-----+------+--------+--------+
| 1 | 1 | 1 | 20 |
| | | 2 | 20 |
| | | 3 | 20 |
| | | 4 | 20 |
+-----+------+--------+--------+
So Virtually I need to use CHECK I think to make sure that players points = score of their team ie (hScore, aScore) and also make sure that the hScore and aScore = the total score in the Game table.
I was thinking of creating a foreign key variable on one of the tables and setting up constraints on that would this be the best way of going about it?
Thanks

Transform ranged data in an Access table

I have a table in Access database as below;
Name | Range | X | Y | Z
------------------------------
A | 100-200 | 1 | 2 | 3
A | 200-300 | 4 | 5 | 6
B | 100-200 | 10 | 11 | 12
B | 200-300 | 13 | 14 | 15
C | 200-300 | 16 | 17 | 18
C | 300-400 | 19 | 20 | 21
I have trying write a query that convert this into the following format.
Name | X_100_200 | Y_100_200 | Z_100_200 | X_200_300 | Y_200_300 | Z_200_300 | X_300_400 | Y_300_400 | Z_300_400
A | 1 | 2 | 3 | 4 | 5 | 6 | | |
B | 10 | 11 | 12 | 13 | 14 | 15 | | |
C | | | | 16 | 17 | 18 | 19 | 20 | 21
After trying for a while the best method I could come-up with is to write bunch of short queries that selects the data for each Range and then put them together again using a Union query. The problem is that for this example I have shown 3 columns (X, Y and Z), but I actually have much more. Access is starting to strain with the amount of SQL I have come up with.
Is there a better way to achieve this?
The answer was simple. Just use Access Pivotview. Finding it hard to export the results to Excel though.

Resources