Where is the mistake for this query logic? - sql

I am working on some project and I have 8 tables I created tasks for my self for improving my knowledge and when I'm doing that I had a Problem during query
In below there is sample tables and data
CREATE TABLE Clients
(ID NUMBER(10),
name VARCHAR(30) NOT NULL,
surname VARCHAR(30) NOT NULL,
Cbudget NUMBER(10,2),
CompanyID NUMBER(10) NOT NULL,
PRIMARY KEY(ID));
Describe Clients
CREATE TABLE Contracts
(ID NUMBER(20),
ContractValue CHAR(255) NOT NULL,
CompanyID NUMBER(10) NOT NULL,
ClientID NUMBER(10) NOT NULL,
TransactionID NUMBER(10) NOt NULL,
PRIMARY KEY(ID));
Describe Contracts
ALTER TABLE Contracts ADD ClientID NUMBER
CREATE TABLE "Transaction"
(ID NUMBER(10),
Type NUMBER(1) NOT NULL,
Price NUMBER(10,2),
TDATE date,
ClientID NUMBER(10) NOT NULL,
PRIMARY KEY(ID));
Describe "Transaction"
here is the data
INSERT INTO Clients(ID,name,surname,Cbudget,CompanyID) VALUES (1,'hamza','bacara',98372.200,2);
INSERT INTO Clients(ID,name,surname,Cbudget,CompanyID) VALUES (2,'','bacara',87432.400,1);
INSERT INTO Clients(ID,name,surname,Cbudget,CompanyID) VALUES (3,'batikan','falay',213132.00,2);
INSERT INTO "Transaction"(ID,Type,Price,TDATE,ClientID)VALUES(1,'1',5000,current_date,2);
INSERT INTO "Transaction"(ID,Type,Price,TDATE,ClientID)VALUES(2,'1',6000,'11/09/2006',1);
INSERT INTO "Transaction"(ID,Type,Price,TDATE,ClientID)VALUES(3,'2',9000,current_date,3);
INSERT INTO Contracts(ID,ContractValue,CompanyID,ClientID,TransactionID)VALUES(1,'1 Million $',1,2,1);
INSERT INTO Contracts(ID,ContractValue,CompanyID,ClientID,TransactionID)VALUES(2,'50 Million $',2,1,2);
INSERT INTO Contracts(ID,ContractValue,CompanyID,ClientID,TransactionID)VALUES(3,'100 Million $',2,2,3);
and here is the query (it works but every time it just shows the data with '100 million $'
SELECT * FROM Contracts WHERE ClientID IN
(SELECT T.ClientID FROM "Transaction" T
INNER JOIN Contracts CT ON CT.TransactionID = CT.id WHERE CT.ContractValue = '1 Million $');
I have also constraints (I'm not sure it's important for you)

Actually, your query is giving the correct result as per your data. (Only one change in the query ...ON CT.TransactionID = CT.id WHERE... should be ...ON CT.TransactionID = T.id WHERE...)
In the CONTRACTS table, CLIENTID 2 is assigned to two contracts ID = 1 and 3. so the query is matching with two clients.
If you will update the CONTRACTS table as follows then it is giving the correct result.
UPDATE CONTRACTS
SET CLIENTID = 3
WHERE ID = 3
db fiddle demo

Related

how to join two/ three tables in postgresql

I am new to creating databases and want to know how to solve this problem or if I'm even doing it right.
I'm trying to join two/three tables, staff, role and staff_role together so that the staff can have more than one role and I'm not sure how to go about it any help is appreciated! , this is my code for these tables:
CREATE TABLE ROLE(
ROLE_ID SERIAL PRIMARY KEY,
ROLE_NAME VARCHAR(50) NULL);
Insert into role(role_name) values('Manager');
Insert into role(role_name) values('Glass_Fibre_Specialist');
Insert into role(role_name) values('Engine_Technician');
Insert into role(role_name) values('Electrician');
Insert into role(role_name) values('General_Technician');
CREATE TABLE STAFF(
STAFF_ID SERIAL PRIMARY KEY,
STAFF_FNAME VARCHAR(35) NOT NULL,
STAFF_LNAME VARCHAR(35) NOT NULL,
ADDR VARCHAR(100) NOT NULL,
POSTCODE VARCHAR(20) NOT NULL,
WORK_EMAIL VARCHAR(150) NOT NULL);
CREATE TABLE STAFF_ROLE(
STAFF_ID int NOT NULL REFERENCES STAFF(STAFF_ID),
ROLE_ID int NOT NULL REFERENCES ROLE(ROLE_ID));`
this is what I tried using to join my tables but I don't think it's right
SELECT
s.Staff,
r.role,
sr.Staff_role
FROM Staff s
INNER JOIN role AS r
ON r.StaffID = s.StaffID
INNER JOIN staff_role sr
ON sr.staff_roleId = r.roleId;
`
I have tried looking at how to join the tables but it has not worked/ I'm not too confident about how to do it, I have also tried adding two types of roles as well, but it kept coming up with errors and I'm kind of stuck

Сreating a calculated field from other tables

I want to create a calculated amount field in the sales table that will accept the total of the items related to this order, but I ran into a problem.
"subqueries cannot be used in the generated column expression."
Please tell me how you can do this, taking into account the fact that the architecture cannot be changed.
CREATE TABLE products (
id bigserial PRIMARY KEY,
name varchar(255) NOT NULL,
description varchar(255) NOT NULL,
price decimal NOT NULL
);
CREATE TABLE sales (
id bigserial PRIMARY KEY,
employee_id int NOT NULL,
created_at timestamp NOT NULL,
amount decimal GENERATED ALWAYS AS ( /* subqueris */ ) STORED
);
CREATE TABLE products_sales (
sales_id int NOT NULL,
product_id int NOT NULL,
PRIMARY KEY (sales_id, product_id)
);

How do i fill my table with data from 3 different tables?

So I am working on a football world cup database. These are my important tables:
CREATE TABLE Countries(
Cid SERIAL PRIMARY KEY,
Name VARCHAR(256) NOT NULL UNIQUE
);
CREATE TABLE Stadiums(
Sid SERIAL PRIMARY KEY,
Name VARCHAR(256) NOT NULL UNIQUE,
Cid INT REFERENCES Countries NOT NULL
);
CREATE TABLE Groups(
Gid SERIAL PRIMARY KEY,
Name VARCHAR(64) NOT NULL,
TYear SMALLINT REFERENCES Tournaments NOT NULL
);
CREATE TABLE Teams(
Tid SERIAL PRIMARY KEY,
Cid INT REFERENCES Countries NOT NULL,
Gid INT REFERENCES Groups NOT NULL
);
CREATE TABLE Matches(
Mid INT PRIMARY KEY,
HomeTid INT REFERENCES Teams NOT NULL,
VisitTid INT REFERENCES Teams NOT NULL,
HomeScore SMALLINT NOT NULL,
VisitScore SMALLINT NOT NULL,
MatchDate DATE NOT NULL,
MatchType VARCHAR(64) NOT NULL,
Sid INT REFERENCES Stadiums NOT NULL
);
CREATE TABLE tempmatches(
year INTEGER,
host_country VARCHAR(255),
match_id INTEGER,
type VARCHAR(255),
date DATE,
location1 VARCHAR(255),
team1 VARCHAR(255),
team2 VARCHAR(255),
score1 INTEGER,
score2 INTEGER
);
so my current problem is that I need to populate the columns HomeTid and VisitId of the Matches table with the tid's from the team's table that corresponds with the country of that team from the countries table but I'm not sure how to do that. I tried a few queries but none of them seemed to work. Has anyone an idea on how to solve this?
Using JOIN keyword you can combine 2 tables data.
Here, in this case, you have to use 3-way join.
Eg:
3-way JOIN can be used in this way:
SELECT * FROM table1 JOIN table2 ON table1.col1=table2.col2 JOIN table3 ON table3.col3=table.col1;
Here the 2 tables will get joined based on the columns mentioned after the "ON" keyword.
Here is a reference link in which JOIN is explained clearly
https://www.w3schools.com/sql/sql_join.asp
Use JOIN operation. In SQL it helps to combine several tables(queries) in one

Sql one to many relationship

In my application I have the following Clients, Products. I want for each Client to have certain Products( one to many relationship) my code :
Tables Creation :
Create Table Client
(
IDC int identity(1,1) not null primary key,
NumeC nvarchar(50),
CIF nvarchar(50) unique
)
Create Table Produs
(
IDP int identity(1,1) not null,
NumeP nvarchar(50),
Cantitate int,
IDC int
)
this the Foreign Key :
Alter table Produs add constraint FK_Client_Produs_IDC
Foreign key (IDC) references Client(IDC)
Select statement Query to join Clients and foreach client to show Products :
Select NumeC,CIF from Client
Inner Join Produs
ON Client.IDC = Produs.IDC
I don't know what am I doing wrong, I just want to show Products for each client. It does not give me that. It just repeats the name of the client, now showing me The products for each client
In your SELECT you don't ever include anything from the Produs table, so why would it show it to you.
Select NumeC,CIF,NumeP
from Client
Inner Join Produs
ON Client.IDC = Produs.IDC

SQL Logic and Aggregate Issue

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.