Different detail levels in one table - sql

EDITED
I'm having a problem with a table, where I need to store measures on different detail levels. My default table is:
Id
TotalQuantity
Amount
1
75
1000
Where TotalQuantity is a sum of quantities from every month.
Now I need to add into my default table an information, what quantities I have each month. These monthly quantities should be in one column, so I used UNION.
The problem is that when I will sum up values from these columns in some reports, TotalQuantity AND OTHER VALUES THAT ARE THE SAME FOR BOTH ROWS will be displayed wrong. How can I possibly store all that information?

You need a fact table at the (id, month) grain, like FactMonthlyTotals(id, month, amount). If you have other data that is not for a particular month it would go on a separate fact table, or perhaps a dimension table.

Related

Remove duplicates from fact table to calculate measure correctly

I'm very new to data warehousing and dimensional modelling. For a uni project I started out with a database that I need to turn into a data warehouse for analyses. To end up with a clean star schema, I had to denormalize a few tables into 1 fact table. The downside to this is the amount of redundancy.
Below is a part of the data from the fact table:
A voyage consists of multiple shipments, and a shipment can consist of multiple different items. In this example, containers 1-2000 of shipment 1 contain item 3, and containers 2001-5000 contain item 1. The total amount of containers for this shipment is 5000, obviously. However, for data analysis purposes, I need to calculate a measure for the total amount of containers per voyage. This presents a problem with the current fact table, because I have a record for each different item. So for voyage 1, the actual total amount should be 9200, but because of the duplication I'll end up with 19400, leading to an incorrect measure.
I need to find a way to get rid of the duplicates in my calculation, but I can't find a way to do so. Any help would be much appreciated.
What you'll need to do is group by your shipments (CTE, inner query, temp table, etc) to get the number of containers per shipment, then group by your voyages to get the number of containers per voyage.
Here's an example with an inner query:
SELECT voyage_id, SUM(num_ship_containers) AS num_voyage_containers
FROM (
SELECT voyage_id, shipment_id, MAX(container_end) AS num_ship_containers
FROM ShippingWarehouse
GROUP BY voyage_id, shipment_id
) AS ship_data
GROUP BY voyage_id;
voyage_id
num_voyage_containers
1
9200
Try it out!

How do you make a SQL table reflect vertical records in a horizontal fashion

I have two tables, one has sales records and one has deduct records. There is a primary key that links the two tables called Sales_ID but there are multiple deduct records that belong to one sales record. I am trying to get the sales information and the deduct information on one line. See below for tables and the desired result.
Sales Table:
Deducts table:
Desired results:
SELECT SALES.SALES_ID, SALES.SALE_QTY, SALES.SALE_AMT
FROM SALES
LEFT JOIN DEDUCTS
ON SALES.SALES_ID = DEDUCTS.SALE_ID
I understand that If I add a deduct code in the select statement I will get duplicates, but I don't know what to try to avoid that.
thanks in advance!

MDX : combining data from different tables

How can I combine data coming from different tables.
Let's assume I have 2 tables:
First with sales:
id shop
id product
date
amount
Second with stocks:
actually, with the same structure
id shop
id product
date
amount
I need to analyze for how many days' stock there is in the shop now. For that I need to calculate the average sale per shop per day for last 20 weeks and then divide the remaining stock by the average sales rate.
How can I achieve this?
This is not a actual problem in MDX as you can combine dimension over different fact tables.
You need to create your 3 dimension (using reference table or similar) :
id_shop -> [Shop]
id_product -> [Product]
date -> [Time]
Now we need to add the two tables as 'fact' tables. Recall that Fact Tables are the ones defining measures.
In icCube create a default Cube, e.g. [Cube], and for each table create a 'measure group' (just click the '+' ).
Bind your tables to the dimension, the 'magic'wand will do the work and create a measure for each table (e.g. [Stock] & [Sales] ).
Once the schema is defined and deployed you can use both measures without taking even noticing they are coming from different tables :
[Measures].[Sales] / [Measures].[Stocks]

Change the discount in the Order Details table on all orders of products of an ordered quantity

how do I write a script to change the discount in the Order Details table on all orders of products of an ordered quantity of more than 50 to that of the largest discount ever given on any product.In the northwinds table?
I just need direction, do I use subqueries and how do I get the largest discount?
You're best off using temp tables.
First, select into a temp table the products and their largest discounts.
Next, select into a temp table a list of product instances (I assume there's a key value) with ordered quantities greater than 50.
Lastly, do an update on your Order Details table joined to the two temp tables. Inner joins in both cases.
If you want to make it a single query, you can make those two temp tables into subqueries, but using temp tables is way more efficient. More code, but easier to parse and runs faster.

SQL Database design question

I have a task to design a SQL database that will record values for the company's commodity products (sku numbers). The company has 7600 unique product items that need to be tracked, and each product will have approximately 200 values over the period of a year (one value per product per day, over the period of a year).
My first guess is that the sku numbers go top to bottom (each sku has a row) and each date is a column.
The data will be used to view in chart / graph format and additional calculations will be displayed against those (such as percentage profit margin etc)
My question is:
- is this layout advisable?
- do I have to be cautious of anything, if this type of data goes back about 15 yrs (each table will represent a year)
Any suggestions?
It better to have 3 columns only - instead of many as you are suggesting:
sku date value
-------------------------
1 2011-01-01 10
1 2011-01-02 12
2 2011-01-01 5
This way you can easily add another column if you want to record something else about a given product per date.
I would suggest a table for your products, and a table for the historical values. Maybe create an index for the historical values based on date if you plan to select for specific time periods.
create table products (
id number primary key,
sku number,
name text,
desc text);
create table values (
id number primary key,
product_id number,
timestamp date,
value number,
foreign key fk_prod_price product_id on product.id);
create index idx_price on values.timestamp;
NOTE: not actual sql, you will have to write your own
If you do like #fiver wrote, you don't have to have a table for each year either. Everything in one table. And add indexes on sku/date for faster searching