Composite Key with Date Key - sql-server

I have a Dimension which uses a composite Primary key to identify a single row (3 keys), and one of those keys happens to be the Date from the Source Table. This Date from the Source i do a Left Join join with the Date Dimension to populate the Fact Table. Is it a problem that i would have Date in the Fact table (FK_Date) and also in this Dimension?
CREATE TABLE [dbo].[Dim_Stg_Visitor]
(
[TestCall] INT NOT NULL,
[VisitorTD] INT NOT NULL,
[Date] Date NOT NULL,
[ISP] NVARCHAR(250) NOT NULL,
[Origin] INT NOT NULL,
[SubOrigin] INT NOT NULL,
[Page] INT NOT NULL,
[SubContact] INT NOT NULL,
...
PRIMARY KEY (TestCall, VisitorTD, Date)
);

Related

How to fix Msg 102, Level 15, State 1, Line 8 error

I'm getting error at [InvoiceId]:
Msg 102, Level 15, State 1, Line 8
Incorrect syntax near 'clustured'
My code:
CREATE TABLE tbl_sales_invoice_info
(
id int identity(1,1) NOT NULL,
invoiceid nvarchar(50) NOT NULL,
invoicedate Date NULL,
customer_id int NULL,
grand_total Float(53) NULL,
total_paid Float(53) NULL,
balance Float(53),
PRIMARY KEY clustured ( [invoiceid] ASC)
);
From the documentation, a primary key in SQL Server is automatically created as a clustered index:
When you create a PRIMARY KEY constraint, a unique clustered index on the column or columns is automatically created if a clustered index on the table does not already exist and you do not specify a unique nonclustered index. The primary key column cannot allow NULL values.
So just try removing the CLUSTERED keyword:
create table tbl_sales_Invoice_info (
id int Identity(1,1) not null,
InvoiceId Nvarchar(50) Not Null,
InvoiceDate date null,
Customer_id int null,
Grand_Total float(53) null,
Total_paid float(53) Null,
Balance Float(53),
primary key ([InvoiceId])
);
You can either remove keyword Clustered or just correct the spelling mistake.
CREATE TABLE tbl_sales_invoice_info
(
id int identity(1,1) NOT NULL,
invoiceid nvarchar(50) NOT NULL,
invoicedate Date NULL,
customer_id int NULL,
grand_total Float(53) NULL,
total_paid Float(53) NULL,
balance Float(53),
PRIMARY KEY Clustered ([invoiceid] ASC)
);

Percent revenue increase since previous year per country

I need to get the percentage increase revenue since last year, per country.
create table Customer
(
customer_mail_address varchar(255) not null,
lastname varchar(50) not null,
firstname varchar(50) not null,
payment_method varchar(10) not null,
payment_card_number varchar(30) not null,
contract_type varchar(20) not null,
subscription_start date not null,
subscription_end date ,
user_name varchar(30) not null,
password varchar(50) not null,
country_name varchar(50) not null,
gender char(1) ,
birth_date date ,
constraint pk_Customer primary key(customer_mail_address),
constraint fk_Customer1 foreign key(country_name) references Country(country_name) ON UPDATE CASCADE,
constraint fk_Customer2 foreign key(contract_type) references Contract(contract_type) ON UPDATE CASCADE,
constraint fk_Customer3 foreign key(payment_method) references Payment(payment_method) ON UPDATE CASCADE,
constraint chk_Customer1 check(subscription_start < subscription_end),
constraint uc_Customer unique(user_name),
constraint chk_Customer2 check(len([password]) >= 8 AND [password] like '%[0-9]%'),
constraint chk_Customer3 check(birth_date < subscription_start),
constraint chk_Customer4 check(user_name NOT LIKE '%[^A-Z0-9]%')
)
create table Watchhistory
(
movie_id integer not null,
customer_mail_address varchar(255)not null,
watch_date date not null,
price numeric(5,2)not null,
invoiced bit not null,
constraint pk_Watchhistory primary key(movie_id, customer_mail_address, watch_date),
constraint fk_Watchhistory1 foreign key(movie_id) references Movie(movie_id),
constraint fk_Watchhistory2 foreign key(customer_mail_address) references Customer(customer_mail_address) ON UPDATE CASCADE ON DELETE CASCADE
)
These two tables are what I use to calculate this. I tried a lot of stuff but nothing really did the trick. This is what I have now to calculate the revenue for each year per country but not the percentage increase per country.
CREATE VIEW OmzetStijgingDalingPerLand AS
SELECT DATEPART(yy,watch_date) as [jaar], country_name, SUM(price) AS [omzet]
FROM Watchhistory w
INNER JOIN Customer c ON w.customer_mail_address = c.customer_mail_address
GROUP BY DATEPART(yy,watch_date), country_name
As it is described in article mentioned before, LAG function is the key
SELECT jaar,
country_name,
omzet,
omzet / LAG(omzet, 1) OVER(PARTITION BY country_name ORDER BY jaar) AS increase_percent
FROM OmzetStijgingDalingPerLand

Can a non-primary key columns be referenced from a foreign key?

Here is table one I want to refer DesignationId to other table but it is not working
create table Employees
(
EmployeeID int identity(1,1) primary key,
EmployeeNumber int not null,
LocationID int not null,
EmployeeName varchar(20) not null,
DesignationID int not null,
CategoryID int not null,
)
Second table is that .. on third row it is showing error
create table Designation
(
DesignationID int primary key ,
JobTitle varchar(20) not null,
CONSTRAINT fk_Designation_Employees
FOREIGN KEY (DesignationID)
REFERENCES Employees (DesignationID),
)
You are creating this incorrectly. Try it this way instead:
create table Designation
(
DesignationID int primary key ,
JobTitle varchar(20) not null,
)
create table Employees
(
EmployeeID int identity(1,1) primary key,
EmployeeNumber int not null,
LocationID int not null,
EmployeeName varchar(20) not null,
DesignationID int not null,
CategoryID int not null,
CONSTRAINT fk_Employees_Designation
FOREIGN KEY (DesignationID)
REFERENCES Designation (DesignationID)
)
Many employees linked to a designation. One-To-Many relationship.

Database management systems_pgadmin III

CREATE TABLE Products
(
pid INT NOT NULL,
pname varchar(50) NOT NULL,
price INT NOT NULL,
stock INT NOT NULL,
PRIMARY KEY (pid)
);
CREATE TABLE Customer
(
Cid INT NOT NULL,
Cname varchar(50) NOT NULL,
Caddress varchar(150) NOT NULL,
Ccontact varchar(20) NOT NULL,
PRIMARY KEY (Cid),
);
CREATE TABLE orders
(
orderid int not null,
quantity int not null,
purchased_on date not null,
totalprice float not null,
Cid INT NOT NULL,
Pid INT NOT NULL,
PRIMARY KEY (orderid),
FOREIGN KEY (pid) REFERENCES Products(pid)
FOREIGN KEY (cid) REFERENCES Customers(pid)
);
why the code is getting not able to run pgadmin III,
thanks.
All the scripts should be corrected as follows. Read the comments in front of corrected lines. All the capitalized column names and table names are placed inside double quotes.
CREATE TABLE "Products"
(
pid INT NOT NULL,
pname varchar(50) NOT NULL,
price INT NOT NULL,
stock INT NOT NULL,
PRIMARY KEY (pid)
);
CREATE TABLE "Customer"
(
"Cid" INT NOT NULL,
"Cname" varchar(50) NOT NULL,
"Caddress" varchar(150) NOT NULL,
"Ccontact" varchar(20) NOT NULL,
PRIMARY KEY ("Cid") -- Removed additional comma (,)
CREATE TABLE orders
(
orderid int not null,
quantity int not null,
purchased_on date not null,
totalprice float not null,
"Cid" INT NOT NULL,
"Pid" INT NOT NULL,
PRIMARY KEY (orderid),
FOREIGN KEY ("Pid") REFERENCES "Products"(pid), -- Added missing comma (,)
FOREIGN KEY ("Cid") REFERENCES "Customer"("Cid") -- Referenced table should be Customer not Customers and reference key should be Cid not pid
);

Figuring out number of dimension table(s) in my case of data warehouse

I am a newbie to data warehousing so go easy on me please.
I am trying to figure out the number of dimensions in this case.
In my transaction database:
I have a table which store Location Codes. Columns are location_code int not null primary key, short_description varchar(10) not null, long_description varchar(100) not null.
I have a table which store Region Codes. Columns are region_code int not null primary key, short_description varchar(10) not null, long_description varchar(100) not null.
I have a table which associates Locations and Regions. Columns are assoc_id int not null primary key, location_code int not null, region_code int not null. 1 Location belongs to only 1 Region.
In my data warehouse database user may want to lookup data by location or by region.
Now I am looking to create dimension table(s) in this case.
Wondering should I be creating 2 dimension tables (1 for Location and 1 for Region) this way?
Create 1 dimension table for Location which also has Region with these columns: location_code int not null primary key, location_short_description varchar(10) not null, location_long_description varchar(100) not null, region_code int not null, region_short_description varchar(10) not null, region_long_description varchar(100) not null
Create 1 dimension table for Region which also has Location with these columns: region_code int not null primary key, region_short_description varchar(10) not null, region_long_description varchar(100) not null, location_code int not null, location_short_description varchar(10) not null, location_long_description varchar(100) not null
OR should I be creating 4 dimension tables (1 for Location, 1 for Region, 1 for Location Region association, 1 for Region Location association) this way?
Create 1 dimension table for Location with these columns: location_code int not null primary key, short_description varchar(10) not null, long_description varchar(100) not null
Create 1 dimension table for Region with these columns: region_code int not null primary key, short_description varchar(10) not null, long_description varchar(100) not null
Create 1 dimension table for Location Region association with these columns: location_code int not null, region_code int not null
Create 1 dimension table for Region Location association with these columns: region_code int not null, location_code int not null
Or is there another way which makes more sense? If yes please do tell
In the Data Warehousing world, what type of relationship is this called and what is the standard way to handle it?
Thanks
I would model the Location und Region in the same dimension (named according the business usage, for example D_Location, or D_Geography).
Hour number will be in the fact table and fact table F_Hour and D_Location will be connected with a surrogate key (a sequence in Oracle or an identity in Sql server).
All the descriptive column for Region and Location could happily live togheter in D_Location (of course Region will not be normalized but this is how it is normally done).
I think you dont need to track association of location and region in the dimension tables. That association can be in the fact table.
I would create 2 dimension tables D_Location & D_Region and 1 fact table F_Hour.
D_Location:
location_code int not null primary key, short_description varchar(10) not null, long_description varchar(100) not null
D_Region:
region_code int not null primary key, short_description varchar(10) not null, long_description varchar(100) not null
F_Hour:
hour_id int not null primary key, location_code int not null, region_code int not null, hours decimal(10,2) not null
F_Hour would have 1 FK to D_Location and 1 FK to D_Region.
To get hours for a particular location_code (#location_code):
select h.location_code, l.short_description, l.long_description, sum(h.hours)
from F_Hour h inner join D_Location l on h.location_code = l.location_code
where h.location_code = #location_code
group by h.location_code, l.short_description, l.long_description
order by h.location_code
To get hours for a particular region_code (#region_code):
select h.region_code, r.short_description, r.long_description, sum(h.hours)
from F_Hour h inner join D_Region r on h.region_code = r.region_code
where h.region_code = #region_code
group by h.region_code, r.short_description, r.long_description
order by h.region_code
Does it make sense?

Resources