due in class on +40
In this assignment, you will learn a bit about the Structured Query Language for databases (SQL), and use SELECT
statements to answer questions about the records in our movie database.
In response to each question, you should provide the requested data as well as the query you typed to produce that data. (I can show you how to copy and paste out of your terminal connection.)
You may do this in groups of three, but as in the cloud assignment, please rotate responsibilities of reading, typing, and taking notes.
On Windows, open PuTTY and use the host name imdb.liucs.net
, user name www-data
, and a password I’ll provide in class.
On the Mac, open the Terminal application, and type:
ssh www-data@imdb.liucs.net
Using either platform, once you see the server’s prompt:
www-data@testbed:~$
You should type:
./dbshell
The next prompt you see will be:
db101=>
This means you’re talking to the PostgreSQL (psql) database on the Rackspace server in Virginia that contains our miniature IMDB clone.
=>
, that means it is ready for a new SQL command. When it ends in ->
, it is expecting you to continue the previous command. Often this means that you forgot to type the semicolon ;
at the end of your command. If you forgot, it’s okay to type it now and press enter.
The first thing we’ll do is ask PostgreSQL what tables it has in the database. Type the command backslash and lowercase d: \d
and press enter. You’ll see a list of tables that includes django_admin_log
, movies_movie
, and users_user
. At this point, psql may put you in “pager mode,” with the prompt :
or (END)
. When in pager mode you can type space to move forward, b
to move back, or q
to exit the pager back to your regular psql prompt.
The tables we’ll focus on are those having to do with movies. You can get a more detailed description of a table by typing
\d movies_person
You’ll see a list of the fields and their data types. For your reference, the fields and types within each movie table are given below.
CREATE TABLE "movies_person" (
"id" integer NOT NULL PRIMARY KEY,
"first_name" varchar(64) NOT NULL,
"last_name" varchar(64) NOT NULL,
"birth_date" date,
"imdb_key" varchar(64),
"created_by_id" integer NOT NULL REFERENCES "users_user" ("id"),
"created_at" datetime NOT NULL
);
CREATE TABLE "movies_movie" (
"id" integer NOT NULL PRIMARY KEY,
"title" varchar(128) NOT NULL,
"year" integer NOT NULL,
"director_id" integer REFERENCES "movies_person" ("id"),
"created_by_id" integer NOT NULL REFERENCES "users_user" ("id"),
"created_at" datetime NOT NULL,
"imdb_key" varchar(64)
);
CREATE TABLE "movies_role" (
"id" integer NOT NULL PRIMARY KEY,
"movie_id" integer NOT NULL REFERENCES "movies_movie" ("id"),
"actor_id" integer NOT NULL REFERENCES "movies_person" ("id"),
"character" varchar(64) NOT NULL,
"created_by_id" integer NOT NULL REFERENCES "users_user" ("id"),
"created_at" datetime NOT NULL
);
The format of the table descriptions above is not exactly what you’ll get from psql’s \d
command, although the field names and types will match. The code above consists of SQL statements that would allow us to recreate these tables on a new server.
Databases support four basic kinds of operations, sometimes known by the memorable acronym “CRUD.”
Acronym SQL verbs
------------ -------------
Create CREATE, INSERT
Retrieve SELECT
Update ALTER, UPDATE
Delete DROP, DELETE
Apparently the designers of SQL thought the acronym was undignified, because they called their retrieve operator “Select.” The rest of this assignment is about using SQL select statements.
The basic form of a select query is “select [fields] from [table];” where you replace the parts in brackets. The simplest way is to just retrieve all the fields, which is written with an asterisk:
select * from movies_movie;
You should see a list of all the data about movies. It will probably enter pager mode, so remember that you can use space to move forward, or q
to exit.
The output can be a bit messy if the table has many fields, especially if they don’t all fit across the screen. A solution to that is to specify just those columns you want, like this:
select title, year from movies_movie;
Try an SQL query to show first name, last name, and birth date in the person table. Provide the correct select statements in your answers.
Try an SQL query to show just the character name and movie ID in the role table.
Do the records you’re seeing appear to be in any particular order?
select title, year from movies_movie order by year;
select title, year from movies_movie order by year desc;
The desc
is for descending order.
select first_name, last_name, birth_date from movies_person
order by birth_date;
Limiting number of records:
select title, year from movies_movie order by year desc limit 1;
Filtering records:
select title, year from movies_movie where year < 1985;
select first_name, last_name, birth_date from movies_person
where birth_date < '1945-01-01';
select first_name, last_name, birth_date from movies_person
where date_part('month', birth_date) = '03';
select first_name, last_name, birth_date from movies_person
where first_name ilike 'j%';
To query fields from different tables we need to join them together using foreign keys.
select title, first_name, last_name
from movies_movie m, movies_person p
where m.director_id=p.id;
select character, title, last_name
from movies_role r, movies_movie m, movies_person p
where r.movie_id = m.id and r.actor_id = p.id;