An SQL Primer - Auwal Genemystudents/lecturenotes/sql_primer.pdf · interacting with an RDBMS...
Transcript of An SQL Primer - Auwal Genemystudents/lecturenotes/sql_primer.pdf · interacting with an RDBMS...
An SQL Primer (Before the Steroids!)
IF you are really serious about being a professional database-driven applications developer, then you badly need SQL as much as an incurable cocaine addict needs the dope. I developed this tutorial as a quick intro to SQL before we start our “Programming on Steroids” series. In future articles and tutorials under the “Programming on Steroids” series, we shall be talking about database-driven applications and more but first things first, what is SQL?
http://www.auwalgene.com
M-Auwal Gene III SpinPoint Software (R&D), Nig.
Saturday, October 01, 2011
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 2
FREE, NOT FOR SALE!
An SQL Primer (Before the Steroids!)
By
M-Auwal Gene III MCPN
Chartered Information Technology Professional
• Written at Home, Kabama Layout, Zaria – Nigeria •
Document Version Date: Saturday, 1st October, 2011. Last Modified/Revised On: Sunday, 11th March, 2012.
YOU are really serious about being a professional database-driven
applications developer, then you badly need SQL as much as an
incurable cocaine addict needs the dope. I developed this tutorial as a
quick intro to SQL before we start our “Programming on Steroids” series. In
future articles and tutorials under the “Programming on Steroids” series, we shall
be talking about database-driven applications and more but first things first,
what is SQL?
Well, SQL stands for “Structured Query
Language” and while most people
pronounce it as “ess-que-ell” just as it
is abbreviated, a good number of
programmers prefer to pronounce it as
“see-quel”.
SQL is not a programming language
but it is common to see it used with
regular programming languages to
communicate with database engines
(like MySQL, SQL-Server, Microsoft
Access, Oracle and the rest of them).
IF
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 3
FREE, NOT FOR SALE!
So, rather than being a programming
language as we know, SQL is better
described as a standard querying
language composed of a series of
statements and clauses which are used
exclusively to communicate or interact
with relational database management
systems (RDBMSs). Communicating or
interacting with an RDBMS includes
storing data into, retrieving data from,
deleting data from, or updating
existing data in an RDBMS.
As a matter of fact, you will soon
discover that when dealing with data
in a database, there would be four
major actions that you will most
frequently perform: create, retrieve,
update, and delete. These activities
are collectively referred to as “CRUD”.
So if someone (probably your manager
or teacher) asks you for a CRUD
diagram, they are simply asking for a
diagram representing what commands
or actions you would execute against a
data store.
So, you could actually call SQL the
“lingua franca” of relational database
management systems and you’d be
very correct! We say so because most
of the self-respecting RDBMSs that we
have around in this era share the same
– or almost the same – set of SQL
words (or SQL commands and
statements, if you like) to accomplish
most of the database definition and
manipulation tasks that such systems
support.
So, if you know the syntax of a good
number of SQL commands or
statements, you could talk to
databases in enterprise-y behemoths
like Oracle 10g or SQLServer as easily
as you could do in those almost-free or
open-source systems like MySQL or
mSQL, for example.
Thus, by now I believe you have
already began to see that it will be a
big (I mean, really BIG!) advantage
for you as a self-respecting
programmer to learn and master SQL;
as this will enable you to interact with
numerous databases across all
platforms without any steep learning
or relearning curve.
With SQL, programmers and/or
database administrators can so easily
do a lot of magic on almost any
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 4
FREE, NOT FOR SALE!
relational database platform without
consulting any oracle (LOL, pun
intended).
Amongst several other things, this
simple SQL of a language allows us to
do the following:
Define or modify the structure of a
database
Change database system security settings
Add user permissions on databases or
tables
Query a database for information
Update the contents of a database
Delete unwanted entries in databases or
tables
...and so much more!
Let me emphasize at this point that
SQL is truly tightly connected with
RDBMSs; but even then, SQL does not
by itself make an RDBMS. It is just a
medium – and an important medium
for that matter – through which
communicating with the DBMS is made
both possible and easy.
In this tutorial, I shall introduce you to
the basics of SQL – mainly how to
write SQL commands to insert data
into tables, update (i.e. modify)
existing data in tables, read data from
tables (for display or whatever) and
delete data from tables. In a follow-up
tutorial to this one, we shall delve a
little deeper into the exciting world of
SQL and use it to perform many more
wonders.
So right now, let’s set the ball rolling,
please…
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 5
FREE, NOT FOR SALE!
WHERE DO I GET SQL, AND HOW DO I INSTALL IT?
OU will recall that I have already said that it is common to see SQL
interspersed within statements of well-known programming languages
like Visual Basic 6.0 or web scripting languages like PHP, but SQL itself is
not a programming language as we know it. So, you don’t download and “install”
or configure SQL on your computer as you do with other programming languages
or tools.
On the contrary, SQL (or the ability to
accept and execute your SQL
statements) already comes along with
any conventional RDBMS package that
you install on your computer machine.
So if you install Microsoft SQL Server
2008 on your computer for example, it
will be able to accept and execute any
correct SQL command you give it.
Likewise MySQL and Microsoft Access.
That being said, it is logical to conclude
by saying that if you already have
Microsoft Access installed on your
computer, then you are ready to start
exploring SQL right away! Microsoft
Access comes along with the Microsoft
Office suite of applications and the one
I shall use for illustrations throughout
this tutorial is Microsoft Access 2007.
THE SQL CHARIOT ROLLS ON FOUR WHEELS!
HAT’S right, SQL is a powerful “chariot” sort of – a chariot upon which
the waves of progress in relational databases ride. Or if you like, you
may say there are four pillars upon which the SQL cathedral stands.
Y
T
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 6
FREE, NOT FOR SALE!
GOOD TO KNOW
In most real-world applications, the multi-user
approach to databases is frequently adopted, where
many users can access the database simultaneously
(from different points). In the multi-user
(client/server model) approach, issues such as
auditing, control and security are all important and
must not be taken lightly.
The client/server model usually has a central
database residing on a single server or several
servers whilst users can access the database over a
network from their own desktop computers or other
devices. In a real life application such as keeping
bank account details or employees’ payroll data, a
strict control of transactions and security must be
maintained. SQL has the following aspects to deal
with such issues:
- Data Control Language or DCL (e.g. GRANT,
REVOKE)
- Data Administration Commands or DAC
(e.g. START AUDIT, STOP AUDIT)
- Transactional Control Commands or TCC
(e.g. SET TRANSACTION, COMMIT,
ROLLBACK, SAVEPOINT)
In this tutorial however, we shall be using Microsoft
Access (2007) and because this is beginner stuff, we
shall assume that we are using Access 2007 as a
single user database (i.e. one user can access the
data at any one time). As such, we shall be
concerned only with the following important aspects
of SQL elements:
- Data Definition Language or DDL (e.g.
CREATE, ALTER, DROP, TRUNCATE)
- Data Manipulation Language or DML (e.g.
INSERT, UPDATE, DELETE)
- Data Query Language or DQL (e.g.
SELECT)
(Okay, maybe you are not a poetry freak like me, so I might as well drop my
fanciful literary devices and come out straight, right?)
Okay, right. So in this introductory
tutorial, we shall introduce the four
fundamental data manipulation
constructs (or commands) that make
SQL so powerful, yet so easy to
understand and use.
These fundamental SQL commands are
the INSERT command, the SELECT
command, the UPDATE command, and
the DELETE command. And, as I
suspect you must be already guessing
by now, these four basic commands
respectively allow you to insert (or
add) new records into your database;
select or retrieve data from your
database (for viewing or transferring);
update or modify existing data in your
database; and delete existing data from
your database.
Before we go any further with our
exploration of SQL however, we need
to prepare the database that we shall
be using to illustrate our working
examples.
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 7
FREE, NOT FOR SALE!
WORKING CONCEPT
In this tutorial, we shall assume that
we would be working with or on a
database for a GSM network service
company. You know, in this age of
ubiquitous technology, GSM telephony
and related services have come to stay.
So, I assume we all know what a GSM
network service company is. (But) in
case you happen not to know, well… I
am referring to such giants as MTN,
GLO, ETISALAT, ZAIN and the rest of
them (in Nigeria).
So we know what GSM telephony is
and we know how it commonly goes:
you buy a GSM phone device (or
“handset”, as it is commonly called in
Nigeria) and you would buy a SIM card
and slot the card into your GSM device.
The SIM card could be for any of the
networks GLO, MTN, ETISALAT, ZAIN
or whichever network you prefer.
At some regular (or irregular)
intervals, you would need to
“recharge” your SIM card with “airtime
credit” so that you could continue to
make calls, send SMS text messages,
browse the Internet, and so on. To
recharge your SIM card, you would
usually buy recharge cards that have
price values worth anything between
N100 – N10,000. Of course, you could
also recharge using other methods
than buying recharge cards, but we
shall not concern ourselves with those
other methods here.
Okay, now you know how the GSM
business goes, right? Right!
So, let’ assume that one of them giant
GSM service companies (MTN, GLO,
ZAIN, ETISALAT, etc) approached us
and asked us to design a database
backend that will enable them keep
accurate track of how their recharge
cards are being used by their
subscribers to recharge their SIM
cards, so that the GSM company could
be able to have reports such as the
following:
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 8
FREE, NOT FOR SALE!
SN Card Serial No. Price Value Loaded By Owner Date Loaded 1 940002755498 400.00 06039485500 Yahuza Abubakar 26-Feb-2012 2 740093873211 200.00 08138449577 Zakary Josephine 29-Feb-2012 3 598837770035 400.00 08039117733 Dauda Adetutu A. 02-Mar-2012 4 883920997111 100.00 08063998780 Chukwudi Ndubuisi 22-Feb-2012 5 626677336699 200.00 06139448855 Zakary Josephine 04-Mar-2012 6 647738829956 750.00 08035187663 Joshua Yohannah 04-Mar-2012 7 321198377465 100.00 08138552290 Atanda Ramota 27-Feb-2012 : : : : : : : : : : : :
That will not be all however, as the GSM service company would want our
database structure to be so designed (and implemented) such that it would also
be capable of correctly answering all of the following queries or questions (and
possibly more):
How many subscribers do we currently have on our network?
List out all subscribers on our network, arranging them by surname in alphabetical order.
How many subscribers have more than one phone numbers on our network?
How many subscribers have exactly one phone number on our network?
How many subscribers were born between January 1st, 1980 and December 31st, 1989?
How many subscribers are male (or female) and were born earlier than 1980?
Which subscriber has the most frequent rate of recharging his/her SIM card?
Which particular SIM card or phone number is currently leading with total worth of airtime
recharges, and who owns the SIM card or phone number?
How many recharge cards are left unused by subscribers and what is the total worth of those
recharge cards?
How many N400 (or any other valued) recharge cards were used by all subscribers over a given
time period (e.g. between March 4, 2012 and March 10, 2012)?
How many N400 (or any other valued) recharge cards were used by a particular subscriber for
all his/her phone numbers over a given time period?
How many N400 (or any other valued) recharge cards were used by a particular subscriber for a
particular phone number over a given time period?
...well, and so many more queries!
BUSINESS RULES:
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 9
FREE, NOT FOR SALE!
GOOD TO KNOW
Actually, I have already developed the database and
populated it with a few records. The database is
saved in Access 2000-2003 format, because we may
wish to use VB6 later to develop interfaces that will
connect to the database and make life easier for the
target users.
VB6 can easily connect to Access 2000-2003
databases using the JET OLEDB 4.0 driver with very
few parameters. For VB6 to connect to Access 2007
and other databases, a more powerful driver (with
many more parameters) is required.
But I want to keep things as simple as possible,
hence the decision to save our database file in
Access 2000-2003 format. We shall use that
database to continue our study of SQL in this
tutorial; and you can download it at the following
URL:
http://www.auwalgene.com/mystudents/lecturenotes/gsm-database.mdb
Assume the following few business rules apply to the database that we are
required to build for our client, the GSM service provider:
i. We want to keep some few details
about each and every subscriber on
the client’s network. Surnames,
other names, gender, date of birth
and tribe are the data we want to
collect and store about each
subscriber.
ii. Any subscriber may have more than
one SIM card on the client network.
iii. Any SIM card can be recharged as
many times as required with
different recharge cards.
iv. Any recharge card can be used to
recharge one and only one SIM card.
v. All recharge cards have face value
(price) as well as unique serial
numbers that are not serial.
vi. Whenever a SIM card is recharged,
the details of the transaction should record the SIM card that was recharged by the
card, not the name of the owner of the SIM card.
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 10
FREE, NOT FOR SALE!
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 11
FREE, NOT FOR SALE!
ENTITIES, E-R DIAGRAMS, RELATIONAL SCHEMA
AND DATA DICTIONARY FOR THE CASE STUDY
1: ENTITIES
SUBSCRIBER(SubscriberID, Surname, OtherNames, Gender, DOB, Tribe)
SIM_CARD(RowID, PhoneNumber, PUK, SubscriberID)
RECHARGE_CARD(RowID, SerialNumber, FaceValuePrice, ExpiryDate)
TRANSACTION(RowID, CardNumber, PhoneNumber, Date, Time)
Notes:
Apart from phone numbers, serial numbers and PUK, some SIM cards also have batch
numbers as well as expiry dates; but we wish to keep things simple and just record the
phone number and PUK. Of course, a SIM card is owned by a subscriber, so we want to
record that subscriber’s ID as well.
PhoneNumber could easily be designated as the primary key in the SIM_CARD entity but
we chose to introduce an auto-number attribute, RowID, to make life easier in the long
run.
SerialNumber in the RECHARGE_CARD entity could also have been used as primary key,
but we introduced an auto-number attribute, RowID. Further, SerialNumber in
RECHARGE_CARD is now called CardNumber in the entity TRANSACTION. This is okay in
as much as it makes things clear and unambiguous.
The TRANSACTION entity keeps track of every time a recharge card is used to recharge
any SIM phone number. Notice that we don’t keep the subscriber’s ID in the
TRANSACTION entity because we can easily trace the subscriber through the phone
number. Besides, we are actually interested in keeping track of recharge cards used to
update SIM phone number credit balances; we are not interested in which subscriber
bought which recharge card (a subscriber might buy a recharge card without using it to
recharge his/her own SIM phone number).
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 12
FREE, NOT FOR SALE!
2: E-R DIAGRAMS
Notes:
A SUBSCRIBER entity must have or own at least one SIM_CARD of the network to be
considered a subscriber; and s/he may have more than one SIM cards of the same
network.
It is possible to have a SIM_CARD that doesn’t belong to a SUBSCRIBER (yet); but if it
does belong to any SUBSCRIBER, then it can belong to one and only one SUBSCRIBER.
It is possible to have a SIM_CARD that has not loaded any RECHARGE_CARD (yet); but if it
loads any RECHARGE_CARD, then it can actually load more than one RECHARGE_CARD.
It is possible to have a RECHARGE_CARD that hasn’t been loaded to a SIM_CARD (yet); but
if it does get loaded, then it can be loaded onto one and only one SIM_CARD.
3: RELATIONAL SCHEMA
Notes:
The process of loading a RECHARGE_CARD onto a SIM_CARD constitutes a TRANSACTION,
and the details of such transactions are recorded in a junction table that is not
originally part of the specs. That junction table is the Transactions_Table seen
above.
Fig. 1
Fig. 2
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 13
FREE, NOT FOR SALE!
4: DATA DICTIONARY
TABLE NAME ATTRIBUTE TYPE LENGTH REQUIRED PK/ FK
FK REFERENCED TABLE
Subscribers_Table
SubscriberID NUMBER AutoNum Y PK
Surname TEXT 30 Y
OtherNames TEXT 50 Y
Gender CHAR 1 Y
DOB DATE/TIME Medium Y
Tribe TEXT 25 N
SIM_Cards_Table
RowID NUMBER AutoNum Y PK
PhoneNumber TEXT 11 Y
PUK TEXT 20 N
SubscriberID NUMBER LONG Y FK Subscribers_Table
Recharge_Cards_Table
RowID NUMBER AutoNum Y PK
SerialNumber TEXT 15 Y
ValuePrice CURRENCY Standard Y
ExpiryDate DATE/TIME Medium N
Transactions_Table
TransactionID NUMBER AutoNum Y PK
PhoneNumber TEXT 11 Y FK SIM_Cards_Table
CardNumber TEXT 15 Y FK Recharge_Cards_Table
DateLoaded DATE/TIME Medium Y
TimeLoaded DATE/TIME Long Time Y
Notes:
The Subscribers_Table is not fully normalized. The Tribe field ought not be there to
store text, since many subscribers could belong to the same tribe. Usually, we would
create a Tribes_Table where all tribes would be stored and then the ID of each tribe
will be stored in the Subscribers_Table instead. However, we want to keep things as
simple (and as easy-to-understand) as possible for now, so we may not worry about
100% normalization at this stage.
“Medium” dates are stored in the format DD-MMM-YYYY. So for example, July 4 1970
will be stored as 04-Jul-1970 instead of 07/04/1970 or 04/07/1970. Actually, it is of
no serious consequence at this stage, but we just prefer that our dates should be stored
in a format that is consistently easy to understand (by humans).
“Long” time is stored in the format HH:MM:SS AM/PM. So for example, 6:24:30 in the
evening will be stored in long format as ‘06:24:30 PM’ instead of ‘18:24:30’.
Now with all of that out of the way, let’s start learning about SQL by using the
database we have created. Remember, you can download the file from my
website at http://www.auwalgene.com/mystudents/lecturenotes/gsm-database.zip
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 14
FREE, NOT FOR SALE!
ADDING DATA TO A TABLE USING THE INSERT STATEMENT
OW, we shall get up to steam by looking at the table called
Subscribers_Table in our gsm-database.mdb database file. We
shall use the table to begin our exploration of SQL’s INSERT command.
Looking at the table (as shown in Fig. 3), we see that the record with RowID 10
belongs to a certain subscriber called Dantala Al-Mustapha whose gender is M
(male) with date of birth 18-Jun-1982 and is Baruba by tribe.
N
Fig. 3
DISCLAIMER: All names, phone numbers, recharge card serial numbers
and other data or information used in this tutorial are for academic
illustration purposes only. They are fictitious names and pieces of data
that were all randomly generated and inserted into the database with
no particular reference to any real persons, either living or dead.
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 15
FREE, NOT FOR SALE!
INSERT INTO Subscribers_Table (Surname, OtherNames, Gender, DOB, Tribe) VALUES ('Dantala', 'Al-Mustapha', 'M', #18-Jun-1982#, 'Baruba');
Of course, we used the graphical user
interface of Microsoft Access to insert
the records in that table, but those
records could also have been inserted
using a number of other ways (such as
using program codes in a language like
VB6 or ASP.NET, or by using SQL
commands at an appropriate prompt).
Now, assuming we want to insert that
record at RowID 10 using SQL
command or statement, how can we do
it?
It’s simple. The SQL statement to
insert that record would be written as
follows:
NOTE: You will remember that the RowID column is actually an auto-number column, so
you actually shouldn’t specify it in your SQL INSERT commands. The Microsoft Access
engine will automatically generate and insert the correct value for the auto-number
column each time you insert a new record to the table.
You will notice that in the above
INSERT statement (SQL COMMAND 1),
we first list out the names of the
columns (enclosing those column
names in brackets and separating
them by commas within the brackets)
before specifying the actual data
values that we want to insert under
each of those columns. Not only that,
you will also notice that the data
values are separated by commas and
listed in such a way that they
correspond to the column names
under which we want them inserted.
Finally, we take care to ensure that the
data types are formatted correctly to
correspond with how the columns are
defined in the database – for example,
Gender, Surname, OtherNames and
Tribe are defined as TEXT (or
STRING), so we enclose their
respective data values in single quotes;
dates are enclosed with the pound or
hash symbol, #; while numbers will be
sent to the database just as-is. Take
note, however, that dates being
enclosed with # symbols is actually a
SQL COMMAND 1
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 16
FREE, NOT FOR SALE!
INSERT INTO Subscribers_Table VALUES ('Victor', 'Aisha Janet', 'F', #27-Aug-1978#, 'Igala');
INSERT INTO Subscribers_Table (Surname, OtherNames, Gender, DOB, Tribe) VALUES ('Lawal', 'Zainab', 'F', #18-Aug-1988#, 'Yoruba');
requirement by Microsoft Access.
Other major SQL implementations like
MySQL and SQL Server use single
quotation marks (') to enclose dates
instead.
Now, the record with RowID 4 in the
Subscribers_Table table could
similarly have been inserted with the
following SQL statement:
The rest of the rows could be added to
Subscribers_Table by using exactly
the same statement format, but
changing the data values each time.
The INSERT statement as used above
requires you to specify three pieces of
information for the command to
execute successfully. These are:
i. The name of the table to insert data
into.
ii. The names of the columns where data
is to be inserted.
iii. The actual data values.
However, SQL also allows you to use a
shortcut whereby you can successfully
insert data into tables without
specifying the names of the columns
where data will be inserted, as in the
following example (SQL COMMAND 3):
Question: Now, how would you write your INSERT statement to put the record
at RowID 23, which has no value for the Tribe field, into Subscribers_Table ?
SQL COMMAND 2
SQL COMMAND 3
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 17
FREE, NOT FOR SALE!
SELECT Surname, OtherNames, Gender, DOB, Tribe
FROM Subscribers_Table;
VIEWING DATA IN A TABLE USING THE SELECT STATEMENT
PART from inserting data into tables, SQL also allows you to retrieve
information from database tables through a process called querying the
database; and the SELECT statement is used to achieve this. To see a list
of all subscribers in the Subscribers_Table table for example, you could use a
SELECT statement like so:
And you would get the following result if your Subscribers_Table already
contains some data as we have created previously:
Surname OtherNames Gender DOB Tribe
------- ---------- ------ --- -----
Emmanuel Babajo Tijjani M 16-Dec-1980 Tiv
Ahmed Auwal M 03-Feb-1978 Hausa
Sani Maiyaki Yelwa M 12-Oct-1984 Kanuri
Lawal Zainab F 16-Aug-1988 Yoruba
Olatunji Adesokan Taiwo M 14-Jan-1968 Yoruba
Nathaniel Daniel M 24-May-1979
Halifa Haafizah F 11-Nov-1977 Fulani
Ilyasu Dan Tanko M 13-Apr-1984
Aliyyu Sule Mai-Turare M 17-Mar-1966 Hausa
Dantala Al-Mustapha M 18-Jun-1982 Baruba
Funsho Oloruntoba M 07-Jul-1979 Yoruba
Chukwudi Okafor M. M 02-Sep-1962 Igbo
Adisa Funmilola Omole F 08-Jun-1984 Yoruba
Victor Aisha Janet F 27-Aug-1978 Igala
Donald Kessienna M 15-May-1971 Ijaw
Muhammed Maimunah Kulu F 18-Dec-1980 Baruba
Sanusi Abubakar Chinko M 22-Jul-1969
Johnson Omolola Suzan F 04-Jan-1987 Yoruba
Yusuf Abdulkareem M 12-Feb-1970
Kakanda Olubukoye T. M 16-Oct-1983 Nupe
Alhassan Saude F 18-Jul-1975 Fulani
Issa Garba Nuruddeen M 27-Apr-1981 Nupe
Wasiu Omodunni Ayoka F 15-Feb-1986
Orummu Gideon Kalu M 14-Jul-1972 Yoruba
Jonathan Ikpeba C. M 03-Mar-1983
A
SQL COMMAND 4
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 18
FREE, NOT FOR SALE!
SELECT Surname, OtherNames, Gender, DOB, Tribe
FROM Subscribers_Table WHERE
Gender = 'F' AND DOB < #01-Jan-1980#;
SELECT Surname, OtherNames, Gender, DOB, Tribe FROM Subscribers_Table WHERE Gender = 'F';
If you wish to see only subscribers that are female, then your SELECT statement
will include a WHERE clause, as in the following example:
And here is what your result should look like:
Surname OtherNames Gender DOB Tribe
------- ---------- ------ --- -----
Lawal Zainab F 16-Aug-1988 Yoruba
Halifa Haafizah F 11-Nov-1977 Fulani
Adisa Funmilola Omole F 08-Jun-1984 Yoruba
Victor Aisha Janet F 27-Aug-1978 Igala
Muhammed Maimunah Kulu F 18-Dec-1980 Baruba
Johnson Omolola Suzan F 04-Jan-1987 Yoruba
Alhassan Saude F 18-Jul-1975 Fulani
Wasiu Omodunni Ayoka F 15-Feb-1986
But if you want to see subscribers who are female and who were born before
1980, then your SELECT statement would include the AND keyword to specify the
criteria:
The above should produce:
Surname OtherNames Gender DOB Tribe
------- ---------- ------ --- -----
Halifa Haafizah F 11-Nov-1977 Fulani
Victor Aisha Janet F 27-Aug-1978 Igala
Alhassan Saude F 18-Jul-1975 Fulani
SQL COMMAND 5
SQL COMMAND 6
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 19
FREE, NOT FOR SALE!
SELECT Surname, OtherNames, Gender, DOB, Tribe
FROM Subscribers_Table WHERE Tribe IS NULL;
Questions: Now, how would you write your SELECT statement to list subscribers
who are:
1. not female and not born before April 11 1977?
2. male and belong to Yoruba tribe?
3. not of Igala tribe and not of Fulani tribe?
4. not not of Fulani tribe?
5. born after 2000 or of Igbo tribe?
6. Kanuri or Tiv by tribe?
7. Hausa or Tiv by tribe and are not not born in September?
HANDLING DATA WITH NULL VALUES USING THE IS NULL CLAUSE
OMETIMES, tables are designed such that some columns might be
allowed to contain empty or unknown values. The Tribe field in
Subscribers_Table in our gsm-database.mdb file is an example of
such “nullable” fields. In SQL statements, the IS NULL clause or operator tests
for the existence of a NULL value in one or more fields. For example, we could use
IS NULL to find those subscribers whose tribe is null using the following SELECT
statement:
S
SQL COMMAND 7
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 20
FREE, NOT FOR SALE!
SELECT Surname, OtherNames, Gender, DOB, Tribe
FROM Subscribers_Table;
We should get the following result from SQL COMMAND 7:
Surname OtherNames Gender DOB Tribe
------- ---------- ------ --- -----
Nathaniel Daniel M 24-May-1979
Ilyasu Dan Tanko M 13-Apr-1984
Sanusi Abubakar Chinko M 22-Jul-1969
Yusuf Abdulkareem M 12-Feb-1970
Wasiu Omodunni Ayoka F 15-Feb-1986
Jonathan Ikpeba C. M 03-Mar-1983
Please do take note that NULL is not the same as zero. A field with a NULL value is
just “nothing” or “undefined” or “unknown”. Some authorities say it is also the
same as “empty”, though others disagree.
SORTING OR ARRANGING QUERY RESULTS IN ASCENDING OR DESCENDING ORDER
USING THE ORDER BY CLAUSE
SUALLY, SQL SELECT statements return results as the records are found
in the database; but most times you would want it to return the results
nicely arranged (in alphabetical order by surname or other names, for
example). So, the SELECT query below will just fetch the records of
every subscriber and give them to us in the order they are found in the table:
U
SQL COMMAND 8
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 21
FREE, NOT FOR SALE!
SELECT Surname, OtherNames, Gender, DOB, Tribe
FROM Subscribers_Table ORDER BY Surname ASC;
And the result returned should look like so:
Surname OtherNames Gender DOB Tribe
------- ---------- ------ --- -----
Emmanuel Babajo Tijjani M 16-Dec-1980 Tiv
Ahmed Auwal M 03-Feb-1978 Hausa
Sani Maiyaki Yelwa M 12-Oct-1984 Kanuri
Lawal Zainab F 16-Aug-1988 Yoruba
Olatunji Adesokan Taiwo M 14-Jan-1968 Yoruba
Nathaniel Daniel M 24-May-1979
Halifa Haafizah F 11-Nov-1977 Fulani
Ilyasu Dan Tanko M 13-Apr-1984
Aliyyu Sule Mai-Turare M 17-Mar-1966 Hausa
Dantala Al-Mustapha M 18-Jun-1982 Baruba
Funsho Oloruntoba M 07-Jul-1979 Yoruba
Chukwudi Okafor M. M 02-Sep-1962 Igbo
Adisa Funmilola Omole F 08-Jun-1984 Yoruba
Victor Aisha Janet F 27-Aug-1978 Igala
Donald Kessienna M 15-May-1971 Ijaw
Muhammed Maimunah Kulu F 18-Dec-1980 Baruba
Sanusi Abubakar Chinko M 22-Jul-1969
Johnson Omolola Suzan F 04-Jan-1987 Yoruba
Yusuf Abdulkareem M 12-Feb-1970
Kakanda Olubukoye T. M 16-Oct-1983 Nupe
Alhassan Saude F 18-Jul-1975 Fulani
Issa Garba Nuruddeen M 27-Apr-1981 Nupe
Wasiu Omodunni Ayoka F 15-Feb-1986
Orummu Gideon Kalu M 14-Jul-1972 Yoruba
Jonathan Ikpeba C. M 03-Mar-1983
(But) if we want the results to be arranged in alphabetical order by surname, we
would include the ORDER BY clause into the query as follows:
ASC there means “ascending”, while DESC would mean “descending”. For the
above query, the result would be arranged in alphabetical order by surname as
follows:
SQL COMMAND 9
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 22
FREE, NOT FOR SALE!
SELECT Surname, OtherNames, Gender, DOB, Tribe
FROM Subscribers_Table ORDER BY Tribe DESC;
Surname OtherNames Gender DOB Tribe ------- ---------- ------ --- ----- Adisa Funmilola Omole F 08-Jun-1984 Yoruba Ahmed Auwal M 03-Feb-1978 Hausa Alhassan Saude F 18-Jul-1975 Fulani Aliyyu Sule Mai-Turare M 17-Mar-1966 Hausa Chukwudi Okafor M. M 02-Sep-1962 Igbo Dantala Al-Mustapha M 18-Jun-1982 Baruba Donald Kessienna M 15-May-1971 Ijaw Emmanuel Babajo Tijjani M 16-Dec-1980 Tiv Funsho Oloruntoba M 07-Jul-1979 Yoruba Halifa Haafizah F 11-Nov-1977 Fulani Ilyasu Dan Tanko M 13-Apr-1984 Issa Garba Nuruddeen M 27-Apr-1981 Nupe Johnson Omolola Suzan F 04-Jan-1987 Yoruba Jonathan Ikpeba C. M 03-Mar-1983 Kakanda Olubukoye T. M 16-Oct-1983 Nupe Lawal Zainab F 16-Aug-1988 Yoruba Muhammed Maimunah Kulu F 18-Dec-1980 Baruba Nathaniel Daniel M 24-May-1979 Olatunji Adesokan Taiwo M 14-Jan-1968 Yoruba Orummu Gideon Kalu M 14-Jul-1972 Yoruba Sani Maiyaki Yelwa M 12-Oct-1984 Kanuri Sanusi Abubakar Chinko M 22-Jul-1969 Victor Aisha Janet F 27-Aug-1978 Igala Wasiu Omodunni Ayoka F 15-Feb-1986 Yusuf Abdulkareem M 12-Feb-1970
To return the query results sorted by Tribe in descending order, you would
write:
You will notice in the output (next page), however, that although we did get our
results arranged in descending order by subscribers’ tribe, the subscribers’
surnames are not arranged in any order per se. For example, you will notice from
the above result that Olatunji comes before Funsho, then Adisa, then
Johnson, then Orummu... even though they are all Yoruba by tribe.
SQL COMMAND 10
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 23
FREE, NOT FOR SALE!
SELECT Surname, OtherNames, Gender, DOB, Tribe FROM Subscribers_Table ORDER BY Tribe DESC, Surname ASC;
Surname OtherNames Gender DOB Tribe ------- ---------- ------ --- ----- Lawal Zainab F 16-Aug-1988 Yoruba Olatunji Adesokan Taiwo M 14-Jan-1968 Yoruba Funsho Oloruntoba M 07-Jul-1979 Yoruba Adisa Funmilola Omole F 08-Jun-1984 Yoruba Johnson Omolola Suzan F 04-Jan-1987 Yoruba Orummu Gideon Kalu M 14-Jul-1972 Yoruba Emmanuel Babajo Tijjani M 16-Dec-1980 Tiv Kakanda Olubukoye T. M 16-Oct-1983 Nupe Issa Garba Nuruddeen M 27-Apr-1981 Nupe Sani Maiyaki Yelwa M 12-Oct-1984 Kanuri Donald Kessienna M 15-May-1971 Ijaw Chukwudi Okafor M. M 02-Sep-1962 Igbo Victor Aisha Janet F 27-Aug-1978 Igala Ahmed Auwal M 03-Feb-1978 Hausa Aliyyu Sule Mai Turare M 17-Mar-1966 Hausa Halifa Haafizah F 11-Nov-1977 Fulani Alhassan Saude F 18-Jul-1975 Fulani Dantala Al-Mustapha M 18-Jun-1982 Baruba Muhammed Maimunah Kulu F 18-Dec-1980 Baruba Nathaniel Daniel M 24-May-1979 Ilyasu Dan Tanko M 13-Apr-1984 Sanusi Abubakar Chinko M 22-Jul-1969 Yusuf Abdulkareem M 12-Feb-1970 Wasiu Omodunni Ayoka F 15-Feb-1986 Jonathan Ikpeba C. M 03-Mar-1983
Won’t be nicer, though, if we could first arrange them in descending order by
tribe and then within each tribe, arrange the subscribers by surname in
ascending order?
The ORDER BY clause actually allows us to independently sort each column of the
result set. So, if we want to sort by Tribe in descending order and then by
surname in ascending order, we could write our query thusly:
The output would then be as follows:
NO
T S
OR
TED
!
SQL COMMAND 11
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 24
FREE, NOT FOR SALE!
Surname OtherNames Gender DOB Tribe ------- ---------- ------ --- ----- Adisa Funmilola Omole F 08-Jun-1984 Yoruba Funsho Oloruntoba M 07-Jul-1979 Yoruba Johnson Omolola Suzan F 04-Jan-1987 Yoruba Lawal Zainab F 16-Aug-1988 Yoruba Olatunji Adesokan Taiwo M 14-Jan-1968 Yoruba Orummu Gideon Kalu M 14-Jul-1972 Yoruba Emmanuel Babajo Tijjani M 16-Dec-1980 Tiv Issa Garba Nuruddeen M 27-Apr-1981 Nupe Kakanda Olubukoye T. M 16-Oct-1983 Nupe Sani Maiyaki Yelwa M 12-Oct-1984 Kanuri Donald Kessienna M 15-May-1971 Ijaw Chukwudi Okafor M. M 02-Sep-1962 Igbo Victor Aisha Janet F 27-Aug-1978 Igala Ahmed Auwal M 03-Feb-1978 Hausa Aliyyu Sule Mai Turare M 17-Mar-1966 Hausa Alhassan Saude F 18-Jul-1975 Fulani Halifa Haafizah F 11-Nov-1977 Fulani Dantala Al-Mustapha M 18-Jun-1982 Baruba Muhammed Maimunah Kulu F 18-Dec-1980 Baruba Ilyasu Dan Tanko M 13-Apr-1984 Jonathan Ikpeba C. M 03-Mar-1983 Nathaniel Daniel M 24-May-1979 Sanusi Abubakar Chinko M 22-Jul-1969 Wasiu Omodunni Ayoka F 15-Feb-1986 Yusuf Abdulkareem M 12-Feb-1970
Notice that all subscribers who are Yoruba by tribe are now sorted in ascending
order by surname within their tribal group. The same can be seen for all the
other tribes too where there is more than one subscriber.
NO
W S
OR
TED
!
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 25
FREE, NOT FOR SALE!
GOOD TO KNOW
SQL has a good number of special
built-in functions called “aggregate
functions”, which can be used to
summarize data in tables.
The ANSI/ISO SQL specifications
provide five aggregate functions.
They are the COUNT(), SUM(),
AVG(), MIN() and MAX() functions.
These functions operate on the target
table's data and then produce a single
value as output.
COUNTING RECORDS IN TABLES USING THE COUNT FUNCTION
EMEMBER somewhere around the
beginning of this tutorial when we said
we want to build a database for a GSM
service provider such that the database would be
capable of correctly answering all of the following
queries or questions (and possibly more)?:
How many subscribers do we currently have on our
network?
List out all subscribers on our network, arranging them
by surname in alphabetical order.
How many subscribers have more than one phone
numbers on our network?
How many subscribers have exactly one phone number
on our network?
How many subscribers were born between January 1st, 1980 and December 31st, 1989?
How many subscribers are male (or female) and were born earlier than 1980?
Which subscriber has the most frequent rate of recharging his/her SIM card?
Which particular SIM card or phone number is currently leading with total worth of airtime
recharges, and who owns the SIM card or phone number?
... and so on?
Well, we have written a shipload of SELECT statements that could fetch all
manners of records for us particularly from Subscribers_Table. But we have
not tried to count how many records are returned by the various queries used so
far. Now is the time to ask SQL to help us automatically count the number of
records found in a table, given one or more conditions. SQL has an aggregate
function called the COUNT() function, which will help us do just that. Now to
answer the question, “how many subscribers do we currently have on our
network?”, we could use the COUNT() function in a SELECT statement as follows:
R
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 26
FREE, NOT FOR SALE!
SELECT COUNT(SubscriberID) FROM Subscribers_Table;
SELECT COUNT(SubscriberID) FROM Subscribers_Table;
SELECT COUNT(Surname) FROM Subscribers_Table;
SELECT COUNT(DOB) FROM Subscribers_Table;
SELECT COUNT(Tribe) FROM Subscribers_Table;
And the above will just return 25 (or the exact number of records you currently
have in your own copy of the Subscribers_Table). As a rule, you could specify
just about any field or column name in the table as a parameter to the COUNT()
function and it should work perfectly all the time. So, the above could be written
in any of the following ways and you should still get the same results:
Please it is important you understand that the COUNT() function gets the number
of rows that would be selected by the query. The function does not actually list
the rows; neither does it sum up the values of rows or columns. It simply counts
the number of rows affected by a query!
So, for now we cannot answer the following two questions because there is a
little more we need to learn about SQL before we can write the statements to
answer them:
“How many subscribers have more than one phone numbers on our network?”
“How many subscribers have exactly one phone number on our network?”
SQL COMMAND 12
SQL COMMAND 13
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 27
FREE, NOT FOR SALE!
SELECT COUNT(SubscriberID) FROM Subscribers_Table
WHERE DOB >= #01-Jan-1980# AND DOB <= #31-Dec-1989#;
Alternative Statement:
SELECT COUNT(SubscriberID) FROM Subscribers_Table
WHERE DOB BETWEEN #01-Jan-1980# AND #31-Dec-1989#;
SELECT COUNT(SubscriberID) FROM Subscribers_Table
WHERE DOB < #01-Jan-1980# AND Gender = 'M';
And if it is the females we want to count, then we’ll have:
SELECT COUNT(SubscriberID) FROM Subscribers_Table
WHERE DOB < #01-Jan-1980# AND Gender = 'F';
However, we have sufficiently learnt enough SQL now to be able to answer these
other two questions:
“How many subscribers were born between January 1st, 1980 and December 31st, 1989?”
“How many subscribers are male (or female) and were born earlier than 1980?”
Now, to answer the question, “how many subscribers were born between January
1st, 1980 and December 31st, 1989?”, we could use the COUNT() function in a
SELECT statement that has a WHERE clause as follows:
And the above should return 12 as the answer.
To answer the question, “how many subscribers are male and were born earlier
than 1980?”, we could also use the COUNT() function in a SELECT statement that
also has a WHERE clause as follows:
SQL COMMAND 14
SQL COMMAND 15
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 28
FREE, NOT FOR SALE!
UPDATE Subscribers_Table SET DOB = # 01-Oct-1960#
WHERE OtherNames = ' Maiyaki Yelwa';
UPDATE Subscribers_Table SET Gender = 'F' WHERE
DAY(DOB) >= 11 AND DAY(DOB) <= 19 AND YEAR(DOB) = 1984;
The first query for counting males should return 10, while the second one for
counting females should return 3 (if your copy of Subscribers_Table contains
exactly the same data we are using for our illustrations in this tutorial).
CHANGING EXISTING DATA VALUES IN A TABLE USING THE UPDATE STATEMENT
QL also allows you to alter the contents of your database so that existing
data values are changed to different values – a process called updating the
database. And yes, as you guessed, the SQL command for that is the
UPDATE command:
The first command searches for any
subscriber whose other names is
'Maiyaki Yelwa' and, if found, sets
that subscriber’s date of birth to
October 1st 1960. Note that although
the above command will actually find
one record (RowID 3) in our database
and change the date of birth as
specified, it will actually apply to all
records that match the WHERE
criterion. Thus if there are actually 7
subscribers whose other names (but
not surname) are 'Maiyaki Yelwa',
then all seven will have their dates of
birth changed to October 1st, 1960.
The second statement changes the
gender of subscribers and sets them to
female for all those born between 11th
and 19th of any month in the year
1984. Note that the second UPADATE
statement could be written in a much
S
SQL COMMAND 16
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 29
FREE, NOT FOR SALE!
UPDATE Subscribers_Table SET Gender = 'F'
WHERE DAY(DOB) BETWEEN 11 AND 19
AND YEAR(DOB) = 1984;
DELETE FROM Subscribers_Table WHERE RowID = 17;
DELETE FROM Subscribers_Table WHERE Gender = 'F'
AND MONTH(DOB) = 10;
DELETE FROM Subscribers_Table;
more elegant way using the BETWEEN
keyword as follows:
DELETING RECORDS IN A TABLE USING THE DELETE STATEMENT
INALLY, you can delete records from tables via the DELETE command.
This command removes entire rows of record at a time, unlike the SELECT
and UPDATE commands which may be constructed in such a way that their
operations could be selectively applied to selected columns of the records they
affect. Here are a few examples of how to use the DELETE statement:
The last statement, DELETE FROM Subscribers_Table, will delete ALL
records in the table!
NOTE that both UPDATE and DELETE commands are usually irreversible
once executed, so always, always use them with caution!
F
SQL COMMAND 18
SQL COMMAND 17
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 30
FREE, NOT FOR SALE!
RETRIEVING RECORDS FROM MORE THAN ONE TABLE – TALKING ABUT JOINS
UR gsm-database.mdb file contains four tables (namely,
Subscribers_Table, SIM_Cards_Table, Recharge_Cards_Table
and Transactions_Table); but all this while we have been working
with only one of them (the Subscribers_Table) just to keep things simple as I
try to gently introduce you to SQL. Now if you get this far, you should be ready to
learn some few more interesting tricks of SQL. In the next few pages that follow,
we shall explain (and you should be able to understand) how to write SQL
statements that could affect data stored in more than one table. Before we begin,
let’s look at the contents of our Subscribers_Table once again:
O
Fig. 4
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 31
FREE, NOT FOR SALE!
With above table (Fig. 4), there is no
way of knowing, for example,
Chukwudi Okafor’s phone
number(s) on the network because
the subscribers’ table does not store
the subscriber’s phone numbers.
(Chukwudi’s record is highlighted
with the red single-line box.)
If we look at the SIM_Cards_Table
(Fig. 5) however, we see that it stores
the ID of subscribers along with SIM
card phone numbers and PUKs (I
decided to leave the PUK values blank
for no particular reason anyway).
Chukwudi’s ID is 12 in
Subscribers_Table, and we can
see that it appears at RowID 4 in
SIM_Cards_Table. The phone
number there is 08160777999 – and
so, Chukwudi Okafor’s phone
number is 08160777999!
Fig. 5
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 32
FREE, NOT FOR SALE!
SELECT Subscribers_Table.Surname,
Subscribers_Table.OtherNames,
SIM_Cards_Table.PhoneNumber
FROM Subscribers_Table, SIM_Cards_Table
WHERE Subscribers_Table.SubscriberID =
SIM_Cards_Table.SubscriberID AND
Subscribers_Table.SubscriberID = 12;
If we go back to
Subscribers_Table and look up
the details of Victor Aisha Janet
(Janet’s record is highlighted with
the green double-line box), we see
that her Row ID is 14 in that table.
And on coming to check the
SIM_Cards_Table, we see that it has
two entries for Janet’s phone
numbers – implying that Janet is
using two SIM cards on the same
network. And what are Janet’s two
phone numbers? Yes, you garrrit:
08062998700 (which occurs at
RowID 2 in SIM_Cards_Table) and
08163849939 (which occurs at
RowID 16).
This process of checking the ID of a
subscriber in Subscribers_Table
and then looking up their ID in the
SIM_Cards_Table to determine
what their phone numbers are is
simply called joining (these two)
tables. A “join” is a relational
database term that is used to
combine two or more tables.
It is not terribly difficult for us to join
these two tables in order to know
who owns which SIM card or phone
numbers (as we have done for
Chukwudi and Janet above); but
how do we tell SQL to help us do it?
Let’s start with trying to find out the
SIM phone number(s) of Chukwudi,
whose Row ID we know to be 12:
The above should produce:
SQL COMMAND 19
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 33
FREE, NOT FOR SALE!
SELECT Subscribers_Table.Surname,
Subscribers_Table.OtherNames,
SIM_Cards_Table.PhoneNumber
FROM Subscribers_Table, SIM_Cards_Table
WHERE Subscribers_Table.SubscriberID =
SIM_Cards_Table.SubscriberID AND
Subscribers_Table.SubscriberID = 14;
Surname OtherNames PhoneNumber
------- ---------- -----------
Chukwudi Okafor M. 08160777999
Now, I hope that doesn’t look so
overwhelming for you but let me
assure you that it is really not as
intimidating as it seems. Here is a
simple explanation of how the above
joined query works:
First, the query will look into the
Subscribers_Table and select all
surnames and other names from
there, and then SIM_Cards_Table is
also looked into where all phone
number records found there are
selected.
After this, the query checks, for each
phone number found in
SIM_Cards_Table, whether that
phone number’s SubscriberID can
be matched with any of the
SubscriberIDs in the records read
from Subscribers_Table. Any pair
that matches is returned as the
query’s result. In this case, only one
matching result would be found
(because the target, Chukwudi,
happens to have only one phone
number in this case).
If we wanted to find out Janet’s
phone numbers, we would write the
query in exactly the same way but
this time around, we would Janet’s
SubscriberID (which is 14) in he
WHERE condition and we would get
two results when the query is run:
SQL COMMAND 20
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 34
FREE, NOT FOR SALE!
SELECT Subscribers_Table.Surname,
Subscribers_Table.OtherNames,
SIM_Cards_Table.PhoneNumber
FROM Subscribers_Table INNER JOIN SIM_Cards_Table
ON Subscribers_Table.SubscriberID =
SIM_Cards_Table.SubscriberID
WHERE Subscribers_Table.SubscriberID = 14;
SELECT Surname, OtherNames, PhoneNumber
FROM Subscribers_Table INNER JOIN SIM_Cards_Table
ON Subscribers_Table.SubscriberID =
SIM_Cards_Table.SubscriberID
WHERE Subscribers_Table.SubscriberID = 14;
The result of the above query should be as shown below:
Surname OtherNames PhoneNumber ------- ---------- -----------
Victor Aisha Janet 08062998700
Victor Aisha Janet 08163849939
We could use the INNER JOIN clause to improve the above query, and that is
what professional database administrators (and programmers) actually love, so
here we go:
OR
Yeah, you could omit the [table-name]. prefixes before the field names and it
would still work fine but – and this is a big ‘but’ – it works only if the field names
of the two (or more) tables are unique. If the tables have the same field names,
then you must explicitly specify the [table-name]. prefixes before the field
names.
SQL COMMAND 21
SQL COMMAND 22
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 35
FREE, NOT FOR SALE!
SELECT (Surname + ' ' + OtherNames) AS FullNames,
COUNT(PhoneNumber) AS Total_Phone_Numbers
FROM Subscribers_Table INNER JOIN SIM_Cards_Table
ON Subscribers_Table.SubscriberID =
SIM_Cards_Table.SubscriberID
GROUP BY (Surname + ' ' + OtherNames);
Question: How will you write a joined query to return the surname and other
names and gender of all subscribers as well as all their phone numbers?
Now let’s try and write SQL statements to answer some more of our initial
questions:
i. How many subscribers have more than one phone numbers on our network?
ii. How many subscribers have exactly one phone number on our network?
iii. Which subscriber has the most frequent rate of recharging his/her SIM card?
iv. Which particular SIM card or phone number is currently leading with total worth of airtime
recharges, and who owns the SIM card or phone number?
v. How many recharge cards are left unused by subscribers and what is the total worth of those
recharge cards?
vi. How many N400 (or any other valued) recharge cards were used by all subscribers over a given
time period (e.g. between March 4, 2012 and March 10, 2012)?
vii. How many N400 (or any other valued) recharge cards were used by a particular subscriber for a
particular phone number over a given time period?
viii. How many N400 (or any other valued) recharge cards were used by a particular subscriber for
all his/her phone numbers over a given time period?
Solution to question (i): “How many subscribers have more than one phone numbers on our network?”
Note that the question just wants to know “how many subscribers have more
than one phone number on the network?”; we are not expected to list the names
of those subscribers. To make it easier for you to understand the required query
that will answer that question however, I will want us to start by just listing the
subscribers first:
SQL COMMAND 23
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 36
FREE, NOT FOR SALE!
The results for the above query
should be as shown in Fig. 6. Note
how the query combines the
subscribers’ surnames and other
names to form their full names on-
the-fly:
SELECT (Surname + ' ' + OtherNames) AS FullNames
This is a rather impressive feature of
SQL, I think!
Now, from the output in Fig. 6, we could see that seven subscribers have more
than one phone number on the network (they all happen to have two phone
numbers actually). These subscribers are:
FullNames Total_Phone_Numbers --------- ------------------- Ahmed Auwal 2 Ilyasu Dan Tanko 2 Issa Garba Nuruddeen 2 Johnson Omolola Suzan 2 Muhammed Maimunah Kulu 2 Olatunji Adesokan Taiwo 2 Victor Aisha Janet 2
Now, one trick we can apply to extract and count the above list of seven
subscribers who have more than one SIM card or phone number on the network
from the general list of all subscribers returned by the query is to use what we
Fig. 6
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 37
FREE, NOT FOR SALE!
SELECT COUNT(Total_Phone_Numbers) FROM
(SELECT (Surname + ' ' + OtherNames) AS FullNames,
COUNT(PhoneNumber) AS Total_Phone_Numbers
FROM Subscribers_Table INNER JOIN SIM_Cards_Table ON
Subscribers_Table.SubscriberID = SIM_Cards_Table.SubscriberID
GROUP BY (Surname + ' ' + OtherNames))
WHERE Total_Phone_Numbers > 1;
SELECT COUNT(Total_Phone_Numbers) FROM
(SELECT (Surname + ' ' + OtherNames) AS FullNames,
COUNT(PhoneNumber) AS Total_Phone_Numbers
FROM Subscribers_Table INNER JOIN SIM_Cards_Table ON
Subscribers_Table.SubscriberID = SIM_Cards_Table.SubscriberID
GROUP BY (Surname + ' ' + OtherNames))
WHERE Total_Phone_Numbers = 1;
call a “nested query” – yes, we can nest a query within another query! Our
nested query could be written as follows:
(I have indented the SELECT query to make it easier for you to see and
differentiate the inner or nested query from the outer query).
Solution to (ii): “How many subscribers have exactly one phone number on our network?”
The solution to this is exactly as above, except that our WHERE clause will test for
total phone numbers = 1 rather than total phone numbers > 1:
The above query should return 15 as the answer, if your copy of the sample gsm-
database.mdb file contains exactly the same set of data as the one we are using
for illustrations in this tutorial.
SQL COMMAND 24
SQL COMMAND 25
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 38
FREE, NOT FOR SALE!
SELECT COUNT(Transactions_Table.TransactionID) AS CountOfTransactionID, Transactions_Table.PhoneNumber
FROM Transactions_Table
GROUP BY Transactions_Table.PhoneNumber;
SELECT COUNT(Transactions_Table.TransactionID) AS
CountOfTransactionID, SIM_Cards_Table.PhoneNumber,
Subscribers_Table.Surname, Subscribers_Table.OtherNames
FROM Subscribers_Table INNER JOIN (SIM_Cards_Table INNER JOIN
Transactions_Table ON SIM_Cards_Table.PhoneNumber =
Transactions_Table.PhoneNumber) ON
Subscribers_Table.SubscriberID = SIM_Cards_Table.SubscriberID
GROUP BY SIM_Cards_Table.PhoneNumber, Subscribers_Table.Surname,
Subscribers_Table.OtherNames;
Solution to question (iii): “Which subscriber has the most frequent rate of recharging his/her SIM
card(s) on our network?”
First, let’s run the following query to just know which phone number has the
highest number of recharges:
And we should get the output shown over there in
Fig. 7 --- --- --- --- --- --- --- ---
We see immediately that phone number
08039584848 has the highest number of
recharges (3). But to answer the question fully,
we need to be able to tell who owns that phone
number, so we must modify the query statement
in SQL COMMAND 26 to the following:
Fig. 7
SQL COMMAND 26
SQL COMMAND 27
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 39
FREE, NOT FOR SALE!
SELECT Transactions_Table.CardNumber, Recharge_Cards_Table.ValuePrice,
Transactions_Table.PhoneNumber AS UsedBy
FROM Recharge_Cards_Table INNER JOIN Transactions_Table ON
Recharge_Cards_Table.SerialNumber = Transactions_Table.CardNumber
ORDER BY Transactions_Table.PhoneNumber;
Which should produce the output shown in Fig. 8:
Right, that is much better. We can not only see the highest buyer, but we can also
see the statistics of other buyers as well. This will be a good place to stop, but if
we really want to show just that one subscriber with the highest buying rate, then
we would need to adjust our query yet again to return just one record.
Exercise: Proceed to adjust the query to show the name, gender and phone
number of just that one subscriber with the highest buying rate.
Solution to question (iv): “Which particular SIM card or phone number is currently leading with total
worth of airtime recharges, and who owns the SIM card or phone number?”
Let’s start by listing all used recharge cards, their face values and the phone
numbers that used them:
Fig. 8
SQL COMMAND 28
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 40
FREE, NOT FOR SALE!
SELECT SUM(Recharge_Cards_Table.ValuePrice) AS TotalBought,
Transactions_Table.PhoneNumber
FROM Recharge_Cards_Table INNER JOIN Transactions_Table ON
Recharge_Cards_Table.SerialNumber = Transactions_Table.CardNumber
GROUP BY Transactions_Table.PhoneNumber
ORDER BY SUM(Recharge_Cards_Table.ValuePrice) DESC;
We see in Fig. 9 that the phone number
08039584848 has the most frequent recharge
transactions with three recharges so far but,
even at that, it is easy to see that the total
worth of the value price of recharge cards used
to recharge that phone number is just 1,550.00
(that is, 750.00 + 400.00 + 400.00). Compare
that to, say, 08062114441 who recharged only
twice so far with a total worth of (1,500.00 +
200.00) or 1,700.00
But in order to really tell which particular SIM card or phone number is currently
leading with total worth of airtime recharges, and who owns the SIM card or
phone number, we need to tweak our SELECT query a bit more:
And what should we get the interesting output shown in Fig. 10, which clearly
shows that phone number 06038585855 is topping the list of the network’s
prime subscribers:
Fig. 9
SQL COMMAND 29
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 41
FREE, NOT FOR SALE!
SELECT SUM(Recharge_Cards_Table.ValuePrice) AS TotalBought,
Transactions_Table.PhoneNumber, Subscribers_Table.Surname,
Subscribers_Table.OtherNames, Subscribers_Table.Gender
FROM Subscribers_Table INNER JOIN (SIM_Cards_Table INNER JOIN
(Recharge_Cards_Table INNER JOIN Transactions_Table ON
Recharge_Cards_Table.SerialNumber = Transactions_Table.CardNumber) ON
SIM_Cards_Table.PhoneNumber = Transactions_Table.PhoneNumber) ON
Subscribers_Table.SubscriberID = SIM_Cards_Table.SubscriberID
GROUP BY Transactions_Table.PhoneNumber, Surname, OtherNames, Gender
ORDER BY SUM(Recharge_Cards_Table.ValuePrice) DESC;
But there is still one more piece of information we need
to show, viz “who is actually that prime subscriber who
owns that SIM card or phone number on this network?”
Well, we need to go another step to answer that
question:
Okay, I agree that the above
query is really, really crazy
and I guess I should just
simply show what the
output should look like (and
we could easily tell from Fig.
11 that the “big boy” on our
network is Kakanda
Olubukoye T.)
Fig. 10
Fig. 11
SQL COMMAND 30
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 42
FREE, NOT FOR SALE!
SELECT COUNT(SerialNumber) AS UnUsedCards, SUM(ValuePrice)
AS TotalValue FROM Recharge_Cards_Table
WHERE SerialNumber NOT IN
(SELECT CardNumber FROM Transactions_Table WHERE
Recharge_Cards_Table.SerialNumber =
Transactions_Table.CardNumber);
SELECT COUNT(Transactions_Table.TransactionID)
FROM Recharge_Cards_Table INNER JOIN
Transactions_Table ON
Recharge_Cards_Table.SerialNumber =
Transactions_Table.CardNumber
WHERE Recharge_Cards_Table.ValuePrice = 400 AND
DateLoaded BETWEEN #04-Mar-2012# AND #10-Mar-2012#;
Solution to (v): “How many recharge cards are left unused by subscribers and what is the total worth of
those recharge cards?”
Can you again see the nested query in the SQL statement above as we saw in the
solution to question (i)? This time around though, notice how we use the NOT IN
clause or operator to filter our query.
Solution to (vi): “How many N400 recharge cards were used by all subscribers over a given time period
(e.g. between March 4, 2012 and March 10, 2012)?”
NOTE: To verify that the above query really returns the true count of recharge
cards used by subscribers, you may create and run the following query to get full
details of the transactions (including subscribers’ names, phone numbers, card
numbers and value prices of the cards):
SELECT Subscribers_Table.SubscriberID, Subscribers_Table.Surname,
Subscribers_Table.OtherNames, Transactions_Table.PhoneNumber,
Fig. 12
SQL COMMAND 32
SQL COMMAND 31
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 43
FREE, NOT FOR SALE!
Transactions_Table.CardNumber, Recharge_Cards_Table.ValuePrice,
Transactions_Table.DateLoaded
FROM Subscribers_Table INNER JOIN (SIM_Cards_Table INNER JOIN
(Recharge_Cards_Table INNER JOIN Transactions_Table ON
Recharge_Cards_Table.SerialNumber = Transactions_Table.CardNumber) ON
SIM_Cards_Table.PhoneNumber = Transactions_Table.PhoneNumber) ON
Subscribers_Table.SubscriberID = SIM_Cards_Table.SubscriberID;
The above query, if typed correctly and if you use the gsm-database.mdb file in
its original form as it accompanies this tutorial, should produce the output shown
in Fig. 13 (I’ve sorted the output on the ValuePrice field to make your checks
easier in this case):
Solution to (vii): “How many N400 recharge cards were used by a particular subscriber for all his/her
phone numbers over a given time period?”
Fig. 13
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 44
FREE, NOT FOR SALE!
SELECT Transactions_Table.PhoneNumber, Subscribers_Table.Surname,
Subscribers_Table.OtherNames, Recharge_Cards_Table.ValuePrice
FROM Recharge_Cards_Table INNER JOIN (Subscribers_Table INNER JOIN
(SIM_Cards_Table INNER JOIN Transactions_Table ON
SIM_Cards_Table.PhoneNumber = Transactions_Table.PhoneNumber) ON
Subscribers_Table.SubscriberID = SIM_Cards_Table.SubscriberID) ON
Recharge_Cards_Table.SerialNumber = Transactions_Table.CardNumber
WHERE DateLoaded BETWEEN #01-Feb-2012# AND #07-Mar-2012#;
Again, I will propose that we start with this one from simple to complex. So, the
first thing we are going to do is just list all subscribers who recharged their SIM
cards or phone numbers between our dates of interest (and let’s say our dates of
interest fall between February 1st 2012 and March 7th, 2012). So, now we can
write our SELECT query like so:
And if we type the statement correctly, we should be rewarded with the output
shown in Fig. 14:
Fig. 14
SQL COMMAND 34
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 45
FREE, NOT FOR SALE!
SELECT Transactions_Table.PhoneNumber, Subscribers_Table.Surname,
Subscribers_Table.OtherNames, Recharge_Cards_Table.ValuePrice
FROM Recharge_Cards_Table INNER JOIN (Subscribers_Table INNER JOIN
(SIM_Cards_Table INNER JOIN Transactions_Table ON
SIM_Cards_Table.PhoneNumber = Transactions_Table.PhoneNumber) ON
Subscribers_Table.SubscriberID = SIM_Cards_Table.SubscriberID) ON
Recharge_Cards_Table.SerialNumber = Transactions_Table.CardNumber
WHERE DateLoaded BETWEEN #01-Feb-2012# AND #07-Mar-2012# AND
Surname='Johnson' AND OtherNames ='Omolola Suzan';
SELECT COUNT(Transactions_Table.TransactionID)
FROM Recharge_Cards_Table INNER JOIN (Subscribers_Table INNER JOIN
(SIM_Cards_Table INNER JOIN Transactions_Table ON
SIM_Cards_Table.PhoneNumber = Transactions_Table.PhoneNumber) ON
Subscribers_Table.SubscriberID = SIM_Cards_Table.SubscriberID) ON
Recharge_Cards_Table.SerialNumber = Transactions_Table.CardNumber
WHERE DateLoaded BETWEEN #01-Feb-2012# AND #07-Mar-2012# AND
Surname='Johnson' AND OtherNames ='Omolola Suzan' AND ValuePrice = 400;
Now we can narrow our search down to a particular subscriber (let’s say we are
interested in Johnson Omolola Suzan) over the same time period:
Finally, we can narrow our search down to recharge cards that are worth 400.00
only and count them out as well:
And we’re done with that. Next question, please?
Fig. 15
SQL COMMAND 35
SQL COMMAND 36
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 46
FREE, NOT FOR SALE!
Solution to (viii): “How many N400 recharge cards were used by a particular subscriber for a particular
phone number over a given time period?”
I leave that for you to do as an exercise.
WE’RE DONE FOR NOW, GOOD BYE!
ELL, that will be all in this brief introduction to SQL. I hope you
found it both useful and enjoyable. We shall discuss some
intermediate and advanced-level concepts of SQL in future tutorials
in our “Programming on Steroids” series.
This practical and Microsoft Access
orientated introduction to SQL is only
the beginning for you. There are
many aspects of SQL that we have not
even mentioned at all in this
introductory tutorial. Even the
SELECT statement alone has so many
more powerful variants that were not
mentioned.
When designing and developing for
very large databases (perhaps a
University’s database that contains
records of tens or hundreds of
thousands of students, staff and
contractors), you would have to move
away from a ‘desktop’ RDBMS like
Microsoft Access and instead,
consider using ‘industrial-strength’
database facilities like MySQL, Oracle
or SQL Server. These RDBMS’s
provide developers with the full
range of SQL commands and are
optimized for very large databases
and data sets.
W
M-Auwal Gene III (2011): Programming on Steroids – An SQL Primer
Downloaded from: http://www.auwalgene.com/mystudents/lecturenotes 47
FREE, NOT FOR SALE!
The SQL examples we have been
examining are a good starting point
for your exploration of relational
database administration. I must
emphasize once more, however, that
it is important to realize that there
are many other aspects to SQL in
general and to the DQL (Data Query
Language) in particular that we have
not touched here.
Well, if you find any bug/errors or
have some suggestion on how to
improve this particular introductory
tutorial or extend it, please do let me
know. [And] very importantly, too,
please kindly go ahead and share this
tutorial for free!
Connect with me on Facebook at: http://www.facebook.com/auwalgene3
Drop me a comment or two on my website: http://www.auwalgene.com/comments
Tell me something via e-mail at: [email protected]
Send SMS text messages to my mobile phone at +234 (0) 8032126160
Thank you for reading, and happy programming!