I'm trying to create and populate three dimensions and a fact tables with data. The dimensions work just fine but i'm unable to get any data into my fact table. If anyone will be so kind to point out what i'm doing wrong - i will be grateful.
Thank you all very much.
create table Customer
(
CUID integer identity(1,1) primary key,
Name varchar (25)
)
insert into Customer select distinct customer from [Data]
create table Agent
(
AID integer identity(1,1) primary key,
Agent varchar (25)
)
insert into Agent select distinct Seller from [Data]
create table Time
(
TID integer identity(1,1) primary key,
Week varchar (25),
Month varchar (25),
Year int
)
insert into Time
(Week,Month,Year)
select distinct Day,Month,Year from [Data]
Create Table Fact
(
CUID integer,
AID integer,
TID integer,
Sale money,
constraint pk_Fact primary key (CUID, AID, TID),
constraint fk1_Fact foreign key (CUID)
references Customer (CUID),
constraint fk2_Fact foreign key (AID)
references Agent (AID),
constraint fk3_Fact foreign key (TID)
references Time (TID),
)
insert into Fact
(CUID, AID, TID, Sale)
SELECT CUID, AID, TID, Sale
FROM Customer,
Agent,
Time,
[Data]
You need to process the cubes. Open it in a Visual Studio 2008 and process it. After that the data will be visible. Did you see the Dimension's mapping with the measures are correct?
Related
i get this error when i execute
SQL71516 :: The referenced table '[dbo].[Stock]' contains no primary or candidate keys that match the referencing column list in the foreign key. If the referenced column is a computed column, it should be persisted.
CREATE TABLE [dbo].[Customer]
(
[Id] INT NOT NULL PRIMARY KEY IDENTITY,
[FirstName] NCHAR(10) NOT NULL,
[LastName] NCHAR(10) NOT NULL,
[Email] NCHAR(10) NOT NULL UNIQUE,
[Mobile] NCHAR(10) NOT NULL
)
CREATE TABLE [dbo].[Stock]
(
[Id] INT NOT NULL PRIMARY KEY IDENTITY,
[name] NCHAR(10) NOT NULL,
[price] INT NOT NULL,
CustomersID int NOT NULL,
FOREIGN KEY (CustomersID) REFERENCES Customer(Id)
ON DELETE CASCADE ON UPDATE CASCADE
)
CREATE TABLE [dbo].[Order]
(
[Id] INT NOT NULL PRIMARY KEY IDENTITY,
[Date] DATE NOT NULL,
[Quantity] INT NOT NULL,
Stock_price int NOT NULL,
[Total Value] AS (Quantity)*(Stock_price) PERSISTED,
CONSTRAINT [FK_Stock_price1] FOREIGN KEY ([Stock_price])
REFERENCES [Stock](price) ON DELETE CASCADE ON UPDATE CASCADE
)
You can only use columns that are uniquely indexed. The price column is not. However, I suspect that the foreign key that's giving you a hard time is actually wrong anyway. I also don't think you should have a CustomerId reference in your Stock table.
in fact, the basic standard database structure for a store is this:
Customer table
id, name [, other details]
Stock table
id, name, price [, other details]
Order table
id, customer id, order date [, other details]
Order details table
id, order id, item id, quantity, price [, other details]
This way, an order is related to a single customer, an can contain multiple items.
The price column in the order details table represents the item price at the date of the order - while the price column in the stock table represents the item's current price.
[Stock].[price] is not a key, that's why you can't define a foreign key on that column.
If 2 products (A and B) in table Stock have the same price, what would be the reference?
You can either set a key on this column, such as UNIQUE but this will prevent you to have differents prices in your table Stock.
I suggest you to use the [Stock].[Id] key as reference for your foreign key, such as :
CREATE TABLE [dbo].[Order]
(
[Id] INT NOT NULL PRIMARY KEY IDENTITY,
[Date] DATE NOT NULL,
[Quantity] INT NOT NULL,
Stock_id int NOT NULL, -- <--- changed column name
[Total Value] AS (Quantity)*(Stock_price) PERSISTED,
CONSTRAINT [FK_Stock_id1] FOREIGN KEY ([Stock_id]) -- <-- changed column name
REFERENCES [Stock](Id) ON DELETE CASCADE ON UPDATE CASCADE
-- ^--^------------------------------------- Notice this
);
I'm building a query based on the fact that they have competed in ten or more places. Note that it does not matter how many sports or competitions they competed in, just how many places they have competed in.
CREATE TABLE Gender (
gender CHAR(1),
description VARCHAR(10),
PRIMARY KEY (gender));
CREATE TABLE People (
ID INT,
name VARCHAR(50),
gender CHAR(1),
height FLOAT,
PRIMARY KEY (ID),
FOREIGN KEY (gender) REFERENCES Gender (gender));
CREATE TABLE Sports (
ID INT,
name VARCHAR(50),
record FLOAT,
PRIMARY KEY (ID),
UNIQUE (name));
CREATE TABLE Competitions (
ID INT,
place VARCHAR(50),
held DATE,
PRIMARY KEY (ID));
CREATE TABLE Results (
peopleID INT NOT NULL,
competitionID INT NOT NULL,
sportID INT NOT NULL,
result FLOAT,
PRIMARY KEY (peopleID, competitionID, sportID),
FOREIGN KEY (peopleID) REFERENCES People (ID),
FOREIGN KEY (competitionID) REFERENCES Competitions (ID),
FOREIGN KEY (sportID) REFERENCES Sports (ID));
If anyone can help me with this it would be much appreciated!
As commented by Brad, you can use a simple aggregated query that JOINs table People with Results, with a HAVING BY clause to filter on the number of competitions each person participated to. It seems like you don’t need to bring in any other table to achieve your goal.
SELECT
p.ID,
p.Name
FROM
People p
Results r ON r.peopleID = p.ID
GROUP BY
p.ID,
p.Name
HAVING COUNT(*) >= 10
Below are my two tables
Student(rno int primary key,name varchar(20))
Fees(id int identity,name varchar(10), amount decimal(10,2), pdate date,
rno int foreign key references Student(rno))
In Fees table [id name rno] gives unique.
So can i create composite primary key on table Fees? or need to add one more table to normalize?
Most of the search on table Fees is based on column rno. So it would be good if i have index on rno.
You can Create Composite Primary Key if you want to be unique set of (id,rno) by below code
create table my_table (
column_a integer not null,
column_b integer not null,
column_c varchar(50),
primary key (column_a, column_b)
);
once you create composite primary key constraint you won't able to insert duplicate combination of rno and id
create one more table of FeesMaster where you entered the which type of fees and its name, if any due, then the price or other details.
This will help in future expansion.
and give reference the FeesMaster id to Fees as FeesID. Always give primary key to auto-increment if it is numeric field.
So your table like this.
Student(rno int primary key with auto-increment,name varchar(20))
FeesMaster(feesid int primary key with auto-increment,name varchar(20), price int, dueprice int) --last 2 is optional or give other detail which work as a master detail
--use this table as a transaction table of both above master table, the logic is
Fees(
id int identity,
rno int foreign key references Student(rno),
feesid id foreign key references FeesMaster(FeesID),
amount decimal(10,2),
pdate date)
Updated :-
Fees
id is primary-key of Fees table which are auto-increment
rno is refernce-key of Student table's rno column
feesid is refernce-key of FeesMaster table's feesid column
So in insert gives the feesid of fees master based on fees name. and to get data, the query looklike
select s.name as studentname, fm.name as feesname
from student s
inner join Fees f on f.rno = s.rno
inner join FeesMaster fm on f.feesid = fm.feesid
For now I have only two tables
CREATE TABLE IF NOT EXISTS company (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR (250) NOT NULL
);
CREATE TABLE IF NOT EXISTS employee (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR (250),
company_id INT,
FOREIGN KEY (company_id) REFERENCES Company (id)
);
I need to create one or two tables to store employees and companies statistic. For employee statistic I need to remember all previous companies of this employee and of cause hire dates and resign dates. For company statistic I need to remember all resigned employees. What is the best way to organize DB structure in my case?
Since you have many-to-many relationship, you need an aggregate table company_employee that will have combined primary key, so you need:
CREATE TABLE IF NOT EXISTS company (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR (250) NOT NULL
);
CREATE TABLE IF NOT EXISTS employee (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR (250)
);
CREATE TABLE IF NOT EXISTS company_employee (
company_id INT NOT NULL,
employee_id INT NOT NULL,
hire_date DATE,
resign_date DATE,
FOREIGN KEY (company_id) REFERENCES Company (id),
FOREIGN KEY (employee_id) REFERENCES Employee (id)
);
So, if you want anything from aggregate table, just use JOIN on key of appropriate table.
I have the following problem to solve in SQL :
d) A query that provides management information on take up of the various types of activities on offer. For each type of activity, the query should show the total number of individuals who took that type of activity and the average number of individuals taking each type of activity.
Here are my tables :
CREATE TABLE accommodations
(
chalet_number int PRIMARY KEY,
chalet_name varchar(40) NOT NULL,
no_it_sleeps number(2) NOT NULL,
indivppw number(4) NOT NULL
)
CREATE TABLE supervisors
(
supervisor_number int PRIMARY KEY,
supervisor_forename varchar(30) NOT NULL,
supervisor_surname varchar(30) NOT NULL,
mobile_number varchar(11) NOT NULL
)
CREATE TABLE visitors
(
visitor_ID int PRIMARY KEY,
group_ID int NOT NULL,
forename varchar(20) NOT NULL,
surname varchar(20) NOT NULL,
dob date NOT NULL,
gender varchar(1) NOT NULL
)
CREATE TABLE activities
(
activity_code varchar(10) PRIMARY KEY,
activity_title varchar(20) NOT NULL,
"type" varchar(20) NOT NULL
)
CREATE TABLE "groups"
(
group_ID int PRIMARY KEY,
group_leader varchar(20) NOT NULL,
group_name varchar(30)
number_in_group number(2) NOT NULL
)
CREATE TABLE bookings
(
group_ID int NOT NULL,
start_date date NOT NULL,
chalet_number int NOT NULL,
no_in_chalet number(2) NOT NULL,
start_date date NOT NULL,
end_date date NOT NULL,
CONSTRAINT bookings_pk PRIMARY KEY(group_ID, chalet_number));
CREATE TABLE schedule
(
schedule_ID int PRIMARY KEY,
activity_code varchar(10) NOT NULL,
time_of_activity number(4,2) NOT NULL,
am_pm varchar(2) NOT NULL,
"date" date NOT NULL
)
CREATE TABLE activity_bookings
(
visitor_ID int NOT NULL,
schedule_ID int NOT NULL,
supervisor_number int NOT NULL,
comments varchar(200),
CONSTRAINT event_booking_pk PRIMARY KEY(visitor_ID, schedule_ID));
ALTER TABLE visitors
ADD FOREIGN KEY (group_ID)
REFERENCES "groups"(group_ID)
ALTER TABLE Schedule
ADD FOREIGN KEY (activity_code)
REFERENCES activities(activity_code)
ALTER TABLE bookings
ADD FOREIGN KEY (group_ID)
REFERENCES "groups"(group_ID)
ALTER TABLE bookings
ADD FOREIGN KEY (chalet_number)
REFERENCES accommodations(chalet_number)
ALTER TABLE activity_bookings
ADD FOREIGN KEY (visitor_ID)
REFERENCES visitors(visitor_ID)
ALTER TABLE activity_bookings
ADD FOREIGN KEY (schedule_ID)
REFERENCES schedule(schedule_ID)
ALTER TABLE activity_bookings
ADD FOREIGN KEY (supervisor_number)
REFERENCES supervisors(supervisor_number)
I have the following solution:
SELECT activities."type", 'overalltotal' AS OT, ('overalltotal' / 'activities') AS AVG
FROM activities, schedule
WHERE 'overalltotal' = (SELECT SUM(COUNT(schedule_ID))
FROM activities, schedule
WHERE schedule.activity_code = activities.activity_code
GROUP BY activities."type"
)
AND 'activities' = (SELECT COUNT(DISTINCT activities."type")
FROM activities
)
AND schedule.activity_code = activities.activity_code
GROUP BY activities."type";
I have implemented sample data and code to check the variables above:
SELECT SUM(COUNT(schedule_ID))
FROM activities, schedule
WHERE schedule.activity_code = activities.activity_code
GROUP BY activities."type";
Result : 20
SELECT COUNT(DISTINCT activities."type")
FROM activities;
Result : 5
However when running the code :
ORA-01722: invalid number
01722. 00000 - "invalid number"
*Cause:
*Action:
EDIT:
Using Dave's Code i have the following output:
Snowboarding 15
sledding 19
Snowmobiling 6
Ice Skating 5
Skiing 24
How would i do the final part of the question?
and the average number of individuals taking each type of activity.
You must use double quotes around column names in Oracle, not single quotes. For example, "overalltotal". Single quotes are for text strings, which is why you're getting an invalid number error.
EDIT: This is probably the type of query you want to use:
SELECT activities."type", COUNT(*) AS total, COUNT(*)/(COUNT(*) OVER ()) AS "avg"
FROM activities a
JOIN schedule s ON a.activity_code=s.activity_code
JOIN activity_bookings ab ON s.schedule_ID=ab.schedule_ID
GROUP BY activities."type";
Basically, because each activity booking has one visitor id, we want to get all the activity bookings for each activity. We have to go through schedule to do that. They we group the rows by the activity type and count how many activity bookings we have for each type.