How to connect two fact tables to one dimensional table - sql

I have two fact tables (HistoricTable, ForecastTable). Both tables use a composite key that combines the productID and WeekID together. The ForecastTable has future weekID's & historic has previous ones. I want both of these ProductID's to reference one Dimensional table called ProductTable. How do I connect them?
My assumption would be to create an additional table that queries HistoricTable & ForecastTable via UNION join and have that connected to the ProductTable. Is this logic correct?
Table Image Layout

I want both of these ProductID's to reference one Dimensional table called ProductTable.
You can establish one foreign key between historic and product and another foreign key between forecast and product.
For example:
create table product (
id int primary key not null,
name varchar(10)
);
create table historic (
product_id int not null references product (id),
week_id int not null,
units_sold int,
primary key (product_id, week_id)
);
create table forecast (
product_id int not null references product (id),
week_id int not null,
forecast_units int,
primary key (product_id, week_id)
);

Related

Is it possible to reference a foreign key to parent table?

CREATE TABLE Product
(
"Product_id" int,
"Stock_quantity" int,
"Product_name" varchar(50),
"Model" varchar(50),
"Average_rating" float(3),
"RAM" int,
"Color" varchar(20),
"Price" float(10),
PRIMARY KEY ("Product_id")
);
CREATE TABLE Sale
(
"Sale_id" int,
"Sale_date" date,
"Employee_id" int,
"Customer_id" int,
"Product_id" int,
"Product_quantity" int,
"Rating" int,
PRIMARY KEY ("Sale_id"),
FOREIGN KEY("Employee_id") REFERENCES Employee("Employee_id") ,
FOREIGN KEY("Customer_id") REFERENCES Customer("Customer_id") ,
FOREIGN KEY("Product_id") REFERENCES Product("Product_id")
);
CREATE TABLE Computer
(
"Type" varchar(10),
"Processor" varchar(20),
"Monitor_size" int
) inherits(Product);
CREATE TABLE Mobile
(
"Os" varchar(30),
"Screen_size" int
) inherits(Product);
Here is my tables while insertion of sale rows I get this error.
ERROR: insert or update on table "sale" violates foreign key constraint "PK_Product_id"
SQL state: 23503
Detail: Key (Product_id)=(12) is not present in table "product".
It says there is no presence of the row, but I can see them when I view the table:
I inserted every product as computer or mobile not as product.
You are stumbling over one of the many quirks with inheritance: There are no “global” constraints on an inheritance hierarchy, consequently you cannot have a foreign key to a inheritance hierarchy.
The primary key you defined on product does not extend to computer.
Even though a SELECT on product will append the results for the inheritance children as well, these are not part of the table parent and consequently cannot be used as target for the foreign key. The foreign key is between sale and product only, the inheritance children are excluded.
There is no proper way to do this with inheritance.
It is better for computer not to be an inheritance child of product, but to have a foreign key to product (with a unique constraint on it), so that the data for a computer object will be split between the two tables. This is somewhat inconvenient for queries, but you can have a foreign key that way.
Here is an example:
CREATE TABLE product (
product_id integer PRIMARY KEY,
prodname text NOT NULL
);
CREATE TABLE computer (
product_id integer PRIMARY KEY,
processor text NOT NULL,
FOREIGN KEY (product_id) REFERENCES product(product_id)
);
CREATE TABLE sale (
sale_id integer PRIMARY KEY,
product_id integer NOT NULL REFERENCES product(product_id)
);
Now there is no direct foreign key reference from sale to computer, but since the product_id of computer and product is identical, you can always find the unique computer for a sale if it exists:
SELECT p.prodname, c.processor
FROM sale s
JOIN product p USING (product_id)
LEFT JOIN computer c USING (product_id)
WHERE sale_id = 42;
If you have more product “subtypes”, you can add more left joins.

Make sure a product has at least one category

Hello wonderful Stackoverflowrians!
I have this DB diagram and I have this postgresql to create the tables:
CREATE TABLE products (
prod_id serial PRIMARY KEY,
name varchar(150) NOT NULL,
description text,
purchase_price numeric(10,2) NOT NULL,
selling_price numeric(10,2) NOT NULL,
weight numeric(10,2),
min_quantity int NOT NULL
);
CREATE TABLE categories (
cat_id serial PRIMARY KEY,
name varchar(100),
parent int REFERENCES categories ON DELETE CASCADE
);
CREATE TABLE product_categories (
prod_id int NOT NULL REFERENCES products,
cat_id int NOT NULL REFERENCES categories,
PRIMARY KEY (prod_id, cat_id)
);
As you see I have categories with multiple sub-categories, products, and table to make relations between them so I can assign multiple categories to a product.
While writing down the create table queries interesting question pop-up in my mind.
I am not sure if it's even possible but, I am trying to find a way to assure that every product is assigned to least one category. Any ideas?
One method of ensuring that every product is in at least one category is to have a "primary" category in the product table:
primary_categoryid int not null references categories(cat_id)
This does make the primary categoryid "different" from other categories, because it is not in the product_categories table.
If you attempt a solution where you require a row in product_categories, then you have a problem. The row in product_categories would need to refer to a valid product -- but a product is not valid (by your definition) until it has a category.

Partitioned view on large parent and child table with foreign key

How can I do partitioned view on SQL Server (Standard edition) on two tables with foreign key - parent and child 1TB each - without changing queries called from application, so that queries are not inefficient?
Here is the schema (simplified): ( or on SQL Fiddle)
CREATE TABLE Product
(`idProduct` int,
`DateProduced` datetime,
`productName` varchar(7),
`description` varchar(55),
PRIMARY KEY (`idProduct`)
);
CREATE TABLE ProductPhoto
(`idProduct` int primary key,
`Image` BLOB);
CREATE TABLE ProductExport
( `idExport` int primary key,
`idProduct` int,
`TimeExported` datetime,
`quantity` int);
alter table ProductPhoto
add constraint fk1_Photo foreign key (`idProduct`) references Product(`idProduct`);
alter table ProductExport
add constraint fk1_Export foreign key (`idProduct`) references Product(`idProduct`);
Here are possibilities:
a) if I make partitioned view on table Product based on DateProduced (partitions would be by month each), I cannot search by table's primary key effectively (SELECT * FROM Product WHERE idProduct=3 will search in all partitions of table Product).
b) if I make partitioned view on table Product based on idProduct, I cannot search by DateProduced effectively.
I have also problem how to make both tables partitioned.
Is it possible to somehow make a reasonable partitioned view with both tables, with no large changes for queries (search all product between dates, get product by productId), so that it wouldnt be too slow?

record addition in sql

I am making an inventory management system.
I wanted to enter products which were bought by the customer in product_sale table.
create table product_sale(
recipt# int primary key identity(1001,1),
product_id int,
product_name varchar(50),
brand_name varchar(50),
prchase_date date,
purchase_time time,
gross_price int,
discount_price int,
retail_price int,
quantity int,
)
the problem is that one customer can buy several items, and they will be inserted in multiple rows but as recipt# is primary key,so the other record will be added on another recipt#
so what should I do either should remove primary key contraint from recipt#
or something more preferred....
--Product info--
CREATE TABLE PRODUCT
(
PRODUCTID INT NOT NULL,
PRODUCT_NAME VARCHAR2(20) NOT NULL,
CONSTRAINT PRODUCT_PK PRIMARY KEY(PRODUCT_ID)
);
--sales info--
CREATE TABLE SALES
(
RECIPT_ID SMALLINT DEFAULT (0) NOT NULL,
PRODUCTID INT DEFAULT (0) NULL,
CONSTRAINT SALES_PK PRIMARY KEY(RECIPT_ID),
CONSTRAINT SALES_PRODUCT_FK FOREIGN KEY(PRODUCTID) REFERENCES PRODUCT(PRODUCT_NAME)
);
Edit[1]: since you elaborated more, I would always want to have two different tables because you want a list of your inventory on one table then on the second table you would want the sales. This helps keep all the clutter away from the view you wish to seek.
Mu suggestion is you should denormalize this table by separating order item and receipt ID. Think this is classic example and you can find lots of examples in web.
For example http://www.tomjewett.com/dbdesign/dbdesign.php?page=manymany.php

Indirect UNIQUE constraint

I've had a following set of tables:
CREATE TABLE sellers (
id integer PRIMARY KEY,
....
);
CREATE TABLE buyers (
id integer PRIMARY KEY,
....
);
CREATE TABLE invoices (
id integer PRIMARY KEY,
number varchar(40),
buyer_id integer REFERENCES buyers(id),
seller_id integer REFERENCES sellers(id),
UNIQUE(seller_id, number),
....
);
The UNIQUE constraint is enforces the constraint that one seller can have only one invoice with given number.
I wanted to create a new table, mostly as a many-to-many relationship between buyers and sellers:
CREATE TABLE suppliers (
id integer PRIMARY KEY,
buyer_id integer REFERENCES buyers(id),
seller_id integer REFERENCES sellers(id),
....
);
As a normalization effort, i would like to change invoices to refer to suppliers, like this:
CREATE TABLE invoices (
id integer PRIMARY KEY,
number varchar(40),
supplier_id integer REFERENCES suppliers(id),
....
);
My question is: how can I replace the UNIQUE constraint?
Use a composite primary key for suppliers:
CREATE TABLE suppliers (
buyer_id integer REFERENCES buyers(id),
seller_id integer REFERENCES sellers(id),
...
PRIMARY KEY (buyer_id, seller_id),
...
);
and keep your invoices table intact, only changing the two foreign keys into one:
CREATE TABLE invoices (
id integer PRIMARY KEY,
number varchar(40),
buyer_id integer,
seller_id integer,
UNIQUE (seller_id, number),
FOREIGN KEY (buyer_id, seller_id)
REFERENCES suppliers (buyer_id, seller_id),
....
);
I guess that this design will be useful, if you plan to have more columns in the suppliers table that are related to the seller - buyer relationship. Otherwise, you could have a view that gathers data from the invoices table:
CREATE VIEW suppliers AS
SELECT DISTINCT buyer_id, seller_id
FROM invoices ;