Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 102 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,49 +70,143 @@ column names in the following tables. We'll use `setup.sql` later.
* A reference to an `id` in table `album` (the album the track is on). This
should be a _foreign key_.

```sql
CREATE TABLE track(
id INTEGER PRIMARY KEY AUTOINCREMENT,
title VARCHAR(128) NOT NULL,
album_id INTEGER NOT NULL,
FOREIGN KEY(album_id) REFERENCES album(id)
);
```

* Create a table called `artist_album` to connect artists to albums. (Note that
an artist might have several albums and an album might be created by multiple
artists.)
* Use foreign keys for this, as well.

```sql
CREATE TABLE artist_album(
id INTEGER PRIMARY KEY AUTOINCREMENT,
artist_id INTEGER NOT NULL,
album_id INTEGER NOT NULL,
FOREIGN KEY(artist_id) REFERENCES artist(id),
FOREIGN KEY(album_id) REFERENCES album(id)
);
```

* Run the queries in the file `setup.sql`. This will populate the tables.
* Fix any errors at this point by making sure your tables are correct.
* `DROP TABLE` can be used to delete a table so you can recreate it with
`CREATE TABLE`.

* Write SQL `SELECT` queries that:
* Show all albums.
```sql
SELECT * FROM album;
```
* Show all albums made between 1975 and 1990.
```sql
SELECT * FROM album WHERE release_year BETWEEN 1975 AND 1990;
```
* Show all albums whose names start with `Super D`.
```sql
SELECT * FROM album WHERE title LIKE 'Super D%';
```
* Show all albums that have no release year.
```sql
SELECT * FROM album WHERE release_year IS NULL;
```

---

Great resources:
* [sqlite-select](http://www.sqlitetutorial.net/sqlite-select/)
* [sqlite-where](http://www.sqlitetutorial.net/sqlite-where/)
* [where-isnull](https://www.dofactory.com/sql/where-isnull)
* [sqlite-avg](http://www.sqlitetutorial.net/sqlite-avg/)
* [formatting sqlite shell output](https://dba.stackexchange.com/a/40672)

---

* Write SQL `SELECT` queries that:
* Show all track titles from `Super Funky Album`.
```sql
SELECT track.title
FROM track
JOIN album ON album.id = track.album_id
WHERE album.title IS 'Super Funky Album';
```
* Same query as above, but rename the column from `title` to `Track_Title` in
the output.

```sql
SELECT track.title AS Track_Title
FROM track
JOIN album ON album.id = track.album_id
WHERE album.title IS 'Super Funky Album';
```
* Select all album titles by `Han Solo`.

```sql
SELECT artist.name AS Artist, album.title AS Album_Title
FROM album
JOIN artist_album ON artist_album.album_id = album.id
JOIN artist ON artist.id = artist_album.artist_id
WHERE artist.name IS 'Han Solo';
```
* Select the average year all albums were released.
```sql
SELECT avg(release_year) FROM album;
```

* Select the average year all albums by `Leia and the Ewoks` were released.
```sql
SELECT AVG(release_year)
FROM album
JOIN artist_album ON artist_album.album_id = album.id
JOIN artist ON artist.id = artist_album.artist_id
WHERE artist.name IS 'Leia and the Ewoks';
```

* Select the number of artists.
```sql
SELECT COUNT(*) AS Number_of_Artists FROM artist;
```

* Select the number of tracks on `Super Dubstep Album`.
```sql
SELECT COUNT(*) AS Number_of_Tracks
FROM track
JOIN album ON album.id = track.album_id
WHERE album.title IS 'Super Dubstep Album';
```

### Exercises, Day 2

Create a database for taking notes.

* What are the columns that a note table needs?

|Columns |Relation |
|:---: |:---: |
|id |Primary |
|title | |
|note_text | |
|date_created | |
|author_id |Foreign |

* If you have a timestamp field, how do you auto-populate it with the date?

Per this [StackOverflow answer](https://stackoverflow.com/a/14462319), use `CURRENT_TIMESTAMP`
as the default value.

* A note should have a foreign key pointing to an author in an author table.

* What columns are needed for the author table?

|Columns |Relation |
|:---: |:---: |
|id |Primary |
|author_name | |

Write queries that:

* Insert authors to the author table.
Expand All @@ -129,9 +223,13 @@ Write queries that:
> Note that SQLite doesn't enforce foreign key constrains by default. You have
> to enable them by running `PRAGMA foreign_keys = ON;` before your queries.

* What happens when you try to delete an author with an existing note?
* How can you prevent this?
* What happens when you try to delete an author with an existing note?<br/>
`FOREIGN KEY constraint failed`<br/>
This happens because we are trying to authors, but will end up leaving notes with foreign keys pointing to nowhere if we do so, so the deletion is stopped.

* How can you prevent this?
We can set `ON DELETE CASCADE`, which will delete all related rows with a foreign key matching the author being deleted.

Submit a file `notes.sql` with the queries that build (`CREATE TABLE`/`INSERT`)
and query the database as noted above.

Binary file added music.db
Binary file not shown.
Binary file added notes.db
Binary file not shown.
66 changes: 66 additions & 0 deletions notes.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
CREATE TABLE note(
id INTEGER PRIMARY KEY AUTOINCREMENT,
title VARCHAR(128) DEFAULT 'New Note',
note_text TEXT,
author_id INTEGER NOT NULL,
date_created DATETIME DEFAULT CURRENT_DATE,
FOREIGN KEY(author_id) REFERENCES author(id) ON DELETE CASCADE
);

CREATE TABLE author(
id INTEGER PRIMARY KEY AUTOINCREMENT,
author_name VARCHAR(64) NOT NULL
);

INSERT INTO author (id, author_name) VALUES (1, "Alfa");
INSERT INTO author (id, author_name) VALUES (2, "Bravo");
INSERT INTO author (id, author_name) VALUES (3, "Charlie");

INSERT INTO note (id, title, note_text, author_id) VALUES (
1,
'My friend Omega',
'My friend, Omega, is the last word when it comes to friendship',
1
);

INSERT INTO note (id, title, note_text, author_id) VALUES (
2,
'Lorem Ipsum',
'Cras aliquam, diam ut pretium ultrices, quam lectus pretium nulla, at molestie lacus nisl sed eros. Aliquam vitae lacus quis quam eleifend mattis. Mauris tempor pulvinar facilisis.',
1
);

INSERT INTO note (id, title, note_text, author_id) VALUES (
3,
'My favorite television channel',
'My favorite television channel on cable is Lifetime. It is the best.',
2
);

INSERT INTO note (id, title, note_text, author_id) VALUES (
4,
'Dissertation on Chocolate Factories',
'Access to the means of chocolate production should not be reserved for the golden-tickted elite, but for the hungry and impoverished masses!',
3
);

.headers ON
.mode column

SELECT *
FROM note
JOIN author ON author.id = note.author_id;

SELECT *
FROM note
WHERE note.id = 4;

SELECT author.author_name, COUNT(note.title) AS Num_of_Notes
FROM note
JOIN author ON author.id = note.author_id
GROUP BY author.author_name;

PRAGMA foreign_keys = ON;

DELETE
FROM author;