SQL Querries, Procedure and Triggers
A company is planning to expand internationally very soon. An SQL Query is needed for preparing a report on foreign markets and potential competitors. The compant has created a database containing a foreignCompetitors table, which has the following structure:
competitor
: the name of the competitor;country
: the country in which the competitor is operating.The report, needs to include the number of competitors per country and an additional row at the bottom that contains a summary: ("Total:", total_number_of_competitors)
For The foreignCompetitors Table
competitor | country |
---|---|
Acme Corp | USA |
GLOBEX | USA |
Openmedia | France |
K-bam | USA |
Hatdrill | UK |
Hexgreen | Germany |
D-ranron | France |
Faxla | Spain |
When the following SQL Query is executed on the foreignCompetitors table, it results into a table with two columns: country and competitors. The first column contains the country name, and the second column contains the number of competitors in this country. The resulting table is sorted by the country names in ascending order. The UNION clause creates an extra row at the bottom with the summary, as required.[execution time limit] 10 seconds (mysql/ms-sql/oracle)
The SQL Query
CREATE PROCEDURE totalCompetitorsSolution()
BEGIN
        SELECT DISTINCT country, COUNT(country) AS competitors FROM foreignCompetitors
        GROUP BY country
        UNION
        SELECT 'Total:' as country, COUNT(country) AS competitors FROM foreignCompetitors;
END
The resulting table of the SQL query
country | competitors |
---|---|
France | 2 |
Germany | 1 |
Spain | 1 |
UK | 1 |
USA | 3 |
Total: | 8 |
In the past, straight "A" students have gotten scholarships to reward them for their excellent grades. This year, though, there has been an increase in the number of detentions given to excellent students, so the administration is going to change the rules. In order to encourage the levels of misbehavior to go down, only well-behaved students will be awarded with scholarships this year. Information about the straight "A" students is stored in the table candidates, and information about all the detentions is stored in the table detentions. Here are their structures:
candidate_id
: the unique candidate ID;candidate_name
: the name of the candidate;detention_date
: the date of the detention (of the date
type);student_id
: the id of the student who got the detention.The candidates table
candidate_id | candidate_name |
---|---|
12 | Gerlinde Addens |
35 | Gerbern Abbey |
44 | Edmond Ramsay |
58 | Svanhild Lacey |
103 | Nita Simons |
The detentions table
detention_date | student_id |
---|---|
2015-10-21 | 12 |
2015-11-19 | 91 |
2016-02-11 | 87 |
2015-12-26 | 44 |
2016-01-19 | 91 |
2015-09-10 | 91 |
2015-12-30 | 12 |
2016-05-19 | 58 |
The following SQL Procedure finds which students should get scholarships this year. From the candidates and detentions tables the Procedure returns a table with a single student_id
column containing the IDs of the students who should get scholarships - students from the candidates table who've never gotten a detention. The IDs of the students in the resulting table is sorted in ascending order.[execution time limit] 10 seconds (mysql/ms-sql/oracle)
The SQL Procedure
CREATE PROCEDURE scholarshipSolution()
BEGIN
        SELECT c.candidate_id AS student_id FROM candidates c
        LEFT JOIN detentions d
        ON c.candidate_id=d.student_id
        WHERE d.detention_date IS NULL;
END
The resulting table of the SQL Procedure
student_id |
---|
35 |
103 |
Only Gerbern Abbey and Nita Simons never got detention, so they will get the scholarships this year.The dates are given in the YYYY-MM-DD format.
Given a list of sights to visit with no visitor allowed to walk between two places if the distance between them is 5 km or more. An SQL Procedure can be used to find all pairs of places that are less than 5 km from each other. The places of interests are stored in a table sights, which has the following attributes:
id
: the unique ID of the place;name
: the name of the place;x
: the x coordinate of the place;y
: the y coordinate of the place.The sights table
id | name | x | y |
---|---|---|---|
1 | Tower of London | 51508.026 | -7.5939 |
2 | Trafalgar Square | 51508.040 | -12.7899 |
3 | London Eye | 51503.538 | -11.9371 |
4 | The Shard | 51504.533 | -8.6028 |
The following SQL Procedure finds all pairs of places such that each pair is less than 5 km away. The distances between the places are calculated with the assumption that they are just points on a 2D map and are returned as a table with the columns place1
and place2
. The places in the pairs are sorted lexicographically.[execution time limit] 10 seconds (mysql/ms-sql/oracle)
The SQL Procedure
CREATE PROCEDURE allPairsSolution()
BEGIN
        SELECT a.name AS place1, b.name AS place2 FROM sights AS a
        LEFT JOIN sights b on a.name < b.name
        WHERE a.name < b.name AND SQRT(POWER((a.x - b.x) ,2) + POWER((a.y - b.y) ,2)) <= 5
        ORDER BY place1, place2;
END
The resulting table of the SQL Procedure
place1 | place2 |
---|---|
London Eye | The Shard |
London Eye | Trafalgar Square |
The Shard | Tower of London |
Unique Keys,Relationships,Business Rules,Anormalies,3NF
All Software Engineers are familiar with Relational Databases. Data is stored in tables known as Entities with each table consisting of columns known as attributes or fields. Each table typically contains a Primary Key which cannot be NULL, must composed of a unique minimum set of colums.
Business Rules
Relationship Types
Now, consider that a Room Reservation System for clients would need to be able to allow booking of guests. Information need would consist of the following:
Reservation System Business Rules
1NF
PK - Room#, Reservation Number
Name | Phone | Room# | RoomType | CheckIn | CheckOut | RoomRate | ActualRoomRate | ReservationNumber | Card# | CardType | CardExpiry |
---|
Here Room# and Reservation Number must be combined to form a Composite Primary Key and the table is in first Normal form
1NF -
2NF
PK - Room#
RoomType | RoomRate |
---|
PK - Reservation Number
Name | Phone | CheckIn | CheckOut | Card# | CardType | CardExpiry |
---|
PK - Room# + ReservationNumber
Reservation Number | Actual Room Rate |
---|
All partial dependencies are removed as in the Room# Table Room Type and Room Rate can be known once the Room# is known. Name,Phone,email,Check in,Check out,Card# Card Type and Card Expiry can be knowm once the Reservation Number is known. Actual Room Rate remains in the initial table because if the Reservation Number or Room# is known the Actual Room Rate cannot be derrived
2NF -
In 2NF form anormarmalies and redundancy usually exist as in this case. A delete anormaly would occur if a guest's credit card information needs to be deleted or updated. Also in 2NF the credit card information is redundant for guests with multiple reserations. For large databases engeneers prefer the 3NF to prevent anormalies and redunancy.
3NF
PK - Card#
CardType | CardExpiry |
---|
PK - email
Name | Phone |
---|
PK - Room Type
RoomRate |
---|
PK - Room#
RoomType |
---|
PK - Reservation Number
CheckIn | CheckOut | Card# |
---|
PK - Room# + ReservationNumber
Reservation Number | Actual Room Rate |
---|
All transitive dependencies have been removed and the result is five tables in 3NF. Card# is a primary key for Card Type and card Expiry. Business Rules allow guests to have similar names or phone numbers but not email. The new RoomType table has a 1:M relationship with the Room# table, similarly the email table has a 1:M relationship with the Resevation Number table. The Card# table has a 1:M relationship with the Reservation Number table. The Room# table and the Reservation Number table both have 1:M relationships with the Room# + Reservation Number table
3NF -
Id fields such as RoomType ID and guestID were also added to the final tables so that primary keys do not contain company data. All anormalies and redundancy from the 2NF form has been removed.
GraphQL, ORM, Firebase, MongoDB, Appwrite
In 2023 no-SQL Databases have become popular for modern web applications like Facebook. Earlier programmers first taught that the most efficient way to query a database was to Noramlize it. Today the excess memeory is used to hold redundant data instead of using relationships so that tables can contain lists instead of foreign keys. This results in wasting memory but faster queries than SQL relational Databases.
Google's noSQL Firebase for example uses documents and collections as its database structure. The Firebase server uses Security Rules to allow reading and writing to the database. appwrite.io and superbase are similar to Firebase.
With the advent of GraphQL over fetching can now be avoided by specifying exactly what fields are needed as GraphQL gives you a single endpoint. The following javascript code how connection to a Firebase database is initialized using an API key provided when creating the Firebase backend.
import firebase from 'firebase';
import app from 'firebase/app';
import auth from 'firebase/auth';
import database from 'firebase/database';
const a1: firebase.app.App = firebase.initializeApp({
apiKey: 'apiKey',
databaseURL: 'databaseURL',
projectId: '42',
})
Below is a screenshot of my Firebase Backend for a mobile Application. The data is stored in documents and collections on the Firebase server.
My Firebase Backend
As a Software Engineer and Computer Scientist I think that both relational and noSQL databases both have their uses from large to small applications.