Skip to content

Commit

Permalink
Merge pull request #34 from LaunchCodeEducation/sql-5
Browse files Browse the repository at this point in the history
SQL Part 5
  • Loading branch information
gildedgardenia authored May 21, 2024
2 parents e0b308a + 3a9522e commit 06fb857
Show file tree
Hide file tree
Showing 14 changed files with 418 additions and 0 deletions.
42 changes: 42 additions & 0 deletions content/sql-part-5/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
+++
pre = "<b>22. </b>"
chapter = true
title = "SQL Part 5: Schemas and CRUD Operations"
date = 2024-04-17T13:28:48-05:00
draft = false
weight = 22
+++

## Learning Objectives

Upon completing all the content in this chapter, you should be able to do the following:

1. Understand what a schema is.
1. Create new tables and add new records to existing tables.
1. Update existing tables.
1. Remove records from a table and delete tables.

## Key Terminology

Here is a list of key terms for this chapter broken down by the page they first appear on. Make note of each term and its definition.

### Schemas

1. schema

### Create

1. `CREATE`
1. temporary tables

## Update

1. `UPDATE`

## Delete

1. `DELETE`

## Content Links

{{% children %}}
24 changes: 24 additions & 0 deletions content/sql-part-5/exercises/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
+++
title = "Exercises: Schemas and CRUD Operations"
date = 2021-10-01T09:28:27-05:00
draft = false
weight = 2
+++

## Getting Started

Open up the `SQL-Part-5-Exercises.ipynb` notebook in `data-analysis-projects/sql-part-5/exercises`.

For the exercises and studio in this chapter, you need to connect to the `JunkDB` named after your class. This database serves as a playground for you to experiment with what you learned in this chapter.

With your new connection configured, click on the junk database in the Object Explorer. Instead of clicking on *Tables*, click on the folder called *Security* and then *Schemas*. You should see a schema with your name on it. When practicing these queries, you will only be able to use your schema.

The example below shows how you can use the same process of finding the schema named after you to find the `HumanResources` schema in the `AdventureWorks2019` Database.

![File Tree, Security Folder to schema folder to individual schemas](./pictures/Schemas.png)

## Submitting Your Work

When finished make sure to push your changes up to GitHub.

Copy the link to your GitHub repository and paste it into the submission box in Canvas for **Exercises: SQL Part 5** and click *Submit*.
Binary file added content/sql-part-5/exercises/pictures/Schemas.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions content/sql-part-5/next-steps.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
+++
title = "Next Steps"
date = 2021-10-01T09:28:27-05:00
draft = false
weight = 4
+++

This closes out the section of the course where we just focus on SQL Server. Here are some additional resources on schemas and CRUD oeprations before you dive into the next chapter.

1. [SQL Shack](https://www.sqlshack.com/crud-operations-in-sql-server/)
1. [Microsoft](https://learn.microsoft.com/en-us/sql/relational-databases/security/authentication-access/create-a-database-schema?view=sql-server-ver16)
1. [SQL Server Tutorial](https://www.sqlservertutorial.net/sql-server-basics/sql-server-primary-key/)
10 changes: 10 additions & 0 deletions content/sql-part-5/reading/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
+++
title = "Reading"
date = 2024-04-17T13:28:48-05:00
draft = false
weight = 1
+++

## Reading Content

{{% children %}}
189 changes: 189 additions & 0 deletions content/sql-part-5/reading/create/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
+++
title = "Create"
draft = false
weight = 2
+++

Previously, we outlined the four types of operations we can perform with SQL queries as CRUD. We have only done read operations so far with `SELECT` queries. Now we get to focus on operations that create new tables and add new records to existing tables.

## Creating Tables

The general syntax to create a new table starts with a `CREATE` statement and includes the names of the columns and their datatypes.

```sql {linenos=table}
CREATE TABLE schema_name.table_name (
Column1Name column1datatype,
Column2Name column2datatype,
.
.
.
ColumnNName columnndatatype
);
```

When creating new tables, you first want to sketch out what columns the table should have. Once you create your table, adding a column after the fact is not advisable. You really want to make sure that you know what that table needs to have before you run your query to create the table.

{{% notice blue Note %}}

Later on in your career, you may learn how to alter a table using the `ALTER TABLE` statement, but for now that is outside the scope of this class. To learn more, check out this article from [Microsoft](https://learn.microsoft.com/en-us/sql/t-sql/statements/alter-table-transact-sql?view=sql-server-ver16).

{{% /notice %}}

Let's say that we work for a major grocery store chain and are part of the team evaluating the success of their rewards program. The database is called `FineFoods`, but the tables associated with the rewards program are going to be grouped together in a schema called `rewards`. As the rewards program rolls out, we want to track which in-app coupons were used by consumers in a table called `used_coupons` to determine what kinds of coupons we want to offer later.

Before we create `used_coupons`, we need to think about what data we want to store and what data type each column should be. To start, let's return to the business issue. The store wants us to analyze what coupons rewards customers used to figure out which coupons should be offered again and when those coupons should be offered. We need to know what the coupon was for, so we need to store the item's name, the manufacturer, the redeemable value of the coupon, and the category the item fell into. We need to know *when* those coupons were used too so we want to store the date when the coupon was used. Finally, we want to give each used coupon a unique identifier so we can easily connect this table to other tables later on.

With all these factors in mind, here is our initial `CREATE` query to make this table.

```sql {linenos=table}
CREATE TABLE rewards.used_coupons (
UsedCouponID int,
ItemCategory varchar(255),
Manufacturer varchar(255),
ItemName varchar(255),
RedeemableValue double,
RedeemedDate date
);
```

While this is a good place to start, we want to make `UsedCouponID` a primary key and add a foreign key to the `coupons` table, so we can count how many times a specific coupon was used. Time to refine our query before we run it!

### Setting Up Primary and Foreign Keys

We want `UsedCouponID` to be a primary key. Furthermore, to make our lives easier, we want to make the primary key automatically increment. That way, the first item added to the table will automatically be given a `UsedCouponID` of 1, the second one will have a `UsedCouponID` value of 2, and so on. Let's alter the column declaration in the `CREATE` statement above.

```sql
UsedCouponID int IDENTITY(1,1) PRIMARY KEY
```

Here, we use the `IDENTITY(x,y)` keyword to designate that SQL Server needs to auto-increment starting at `x` and increasing by `y`. `IDENTITY(1,1)` means that SQL Server should start with a primary key of 1 and increase by 1.

Now we can add a foreign key column called `CouponID` that references the primary key column called `CouponID` in a table called `coupons` table.

```sql
CouponID int FOREIGN KEY REFERENCES coupons(CouponID)
```

If we add a primary key and a foreign key to our table, then our `CREATE` statement would now look like:

```sql {linenos=table}
CREATE TABLE rewards.used_coupons (
UsedCouponID int IDENTITY(1,1) PRIMARY KEY,
CouponID int FOREIGN KEY REFERENCES coupons(CouponID),
ItemCategory varchar(255),
Manufacturer varchar(255),
ItemName varchar(255),
RedeemableValue double,
RedeemedDate date
);
```

### Temporary Tables

**Temporary tables** or temp tables are often used when you may not have certain permissions on a database but need to run queries in your everyday work. Only you can see the temp table you create in the connection you created it in. You cannot access the temp table from another workspace/window/notebook. When you close the connection the table has been created in, it’s automatically deleted.

You can make a temporary table by adding a hashtag in front of the table name. If we wanted to make a temporary table for the rewards program for just ice cream coupons, we would run the following query.

```sql {linenos=table}
CREATE TABLE #IceCreamCoupons (
IceCreamCouponID int,
ItemName varchar(255)
);
```

## Adding Records

With our table set up, we can add a new record using the `INSERT` statement. When adding a new record, we can use the following general syntax:

```sql {linenos=table}
-- Inserting a record with values for each column in the table

INSERT INTO schema_name.table_name
VALUES (Column1, Column2, ..., ColumnN);

-- Inserting a record with values for some of the columns in the table

INSERT INTO schema_name.table_name (Column2Name, Column5Name, ...)
VALUES (Column2, Column5, ...);
```

If we wanted to add a new coupon for candy to the `used_coupons` table, we would write the following:

```sql
INSERT INTO rewards.used_coupons (CouponID, ItemCategory, Manufacturer, ItemName, RedeemableValue)
VALUES (276, 'candy', 'Trolli', 'Sour Brite Crawlers', 1.00);
```

We do not have to specify the primary key column because we set that column auto-increment so SQL Server will add a value for that column automatically. In the above query, since we do not have a redeemed date for this coupon, that value will remain `NULL` for now.

## Check Your Understanding

{{% notice green Question %}}

Which of the following queries would you use to create a table called recipes, that holds name (up to 25 characters), description (up to 50 characters), and instructions (up to 500 characters).

1. ``` sql
CREATE TABLE schema_name.recipes(
name VARCHAR(25),
description VARCHAR(50),
instructions VARCHAR(500),
);
```

1. ```sql
MAKE TABLE schema_name.recipes(
name VARCHAR(25),
description VARCHAR(50),
instructions VARCHAR(500),
);
```

1. ```sql
CREATE TABLE schema_name.recipes(
name,
description,
instructions,
);
```

1. ```sql
CREATE TABLE schema_name.recipes(
name (25),
description (50),
instructions (500),
);
```

{{% /notice %}}

<!-- 1 -->

{{% notice green Question %}}

Which of the following queries would add information into the `Recipes` table below.

![Recipes table with one row](./pictures/recipesTables1.png)

1. ```sql
INSERT INTO schema_name.Recipes (name, description, instructions)
VALUES('Pizza', 'To lazy to cook but hungry', 'Call ModPizza and order for delivery');
```

1. ```sql
ADD ROW schema_name.Recipes (name, description, instructions)
VALUES('Pizza', 'To lazy to cook but hungry', 'Call ModPizza and order for delivery');
```

1. ```sql
INSERT INTO schema_name.Recipes (2, name, description, instructions)
VALUES('Pizza', 'To lazy to cook but hungry', 'Call ModPizza and order for delivery')
```

1. ```sql
ADD ROW schema_name.Recipes (2, name, description, instructions)
VALUES('Pizza', 'To lazy to cook but hungry', 'Call ModPizza and order for delivery')
```

{{% /notice %}}

<!-- 1 -->
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
66 changes: 66 additions & 0 deletions content/sql-part-5/reading/delete/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
+++
title = "Delete"
draft = false
weight = 4
+++

Finally, we can remove both records and tables as part of the delete in CRUD. Let's dive back into the grocery store rewards program to learn how to do so! Removing any data in SQL Server is a permanent change and the data cannot be recovered so practice is key!

## Delete a Row

`DELETE` statements include a `WHERE` clause so that we can specify what condition must be met in the data we want to remove.

```sql
DELETE FROM schema_name.table_name WHERE condition met;
```

In the case of the rewards program, we have learned that clear Pepsi was discontinued and we need to remove the record for used coupons for that product from our table. Clear Pepsi has a `CouponID` of 13, so we would write our query like so:

```sql
DELETE FROM rewards.used_coupons WHERE CouponID = 13;
```

Typically, when you write a query like this, SQL Server will output how many rows were affected. If you want to run a check before you delete records from the table, you could use your aggregate functions to see how many rows *should* be affected and compare the two numbers upon deletion to make sure that all rows were removed.

## Delete a Table

If we ever got rid of the app and wanted to remove all records of in-app coupon usage, we could run the following query:

```sql {linenos=table}
DROP TABLE rewards.used_coupons
```

When dropping tables, we want to ensure that we don't have any existing connections to other tables. If `UsedCouponID` is used as a foreign key in another table, we would need to first sever that connection before we can drop a table.

{{% notice blue Note %}}

If you are curious on how to get rid of a foreign key referencing a table you want to drop, you should check out this [article](https://www.w3schools.com/sql/sql_ref_drop_constraint.asp) on `DROP CONSTRAINT`.

{{% /notice %}}

## Check Your Understanding

{{% notice green Question %}}

Write a query to delete any records with a `Description` of Frozen from the `Recipes` table below.

![Recipes table with four rows](./pictures/recipesTable3.png)

{{% /notice %}}

{{% notice green Question %}}

Write a query to clear all the contents of the `Recipes` table.

{{% /notice %}}

{{% notice green Question %}}

Which of the following queries will delete the entire `Recipes` table?

1. `DROP TABLE schema_name.Recipes;`
1. `REMOVE TABLE schema_name.Recipes;`
1. `FROM schema_name DROP TABLE Recipes;`
1. `DELETE TABLE schema_name.Recipes;`

{{% /notice %}}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions content/sql-part-5/reading/schemas/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
+++
title = "Schemas"
draft = false
weight = 1
+++

Before we can dive into the queries, we need to talk about schemas.

A **schema** is a way to group database objects(tables, views, ect) into a logical collection.
Let's look at the `AdventureWorks2019` database in Azure Data Studio.

In the Object Explorer, if you expand the tables, you will see something like this:

![File Tree, Tables Folder with Human Resources schemes highlighted](./pictures/TableSchemas.png)

Notice how the tables are grouped together. The syntax is `schema_name.table_name`.
You wouldn't want someone accidentally deleting a table or being able to view sensitive information.
Schemas allow companies to easily control who has access to specific tables and how they have access.

Another way to think of schemas is that they are like using folders on your Google Drive.
You can group together like-documents and control who has access by granting different permissions to different people.
At any time you can also change permissions or remove someone from having access. You can also move documents from one folder to another.
Multiple people can work together in each folder. The creator of the folder or document is the owner.
But, you can easily reassign the ownership to another person. The same is true of schemas.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 06fb857

Please sign in to comment.