You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

5.5 KiB

Intermediate SQL

Lesson Objectives tools

  1. Alter a table
  2. Limit
  3. Sorting
  4. Aggregation
  5. Joins

Alter a table

After you've created a table, you can always make changes

Add a test string column

ALTER TABLE users ADD COLUMN test VARCHAR(20);

Drop (delete) the test column

ALTER TABLE users DROP COLUMN test;

Rename a column:

ALTER TABLE users RENAME name TO first_name

Add an id column that increments with each new row (we'll talk about PRIMARY KEY later)

ALTER TABLE users ADD COLUMN id serial PRIMARY KEY;

Rename a table

ALTER TABLE users RENAME TO people;

Change the data type of a column:

ALTER TABLE people ALTER COLUMN first_name TYPE text;

Limit

Sometimes it's advantageous to display less than the entire data set:

  • If you want to paginate the data for the end user
  • If you have a really massive amount of data, and the queries take a long time to run

Select all rows from people table, but show only the two rows

SELECT * FROM people LIMIT 2;

Select all rows from people table, but show only the second pair of rows

SELECT * FROM people LIMIT 2 OFFSET 2;

Sorting

With sorting, you can begin to start retrieving interesting information from your data

Select all rows from people table, order by name alphabetically:

SELECT * FROM people ORDER BY first_name ASC;

Select all rows from people table, order by name reverse alphabetically

SELECT * FROM people ORDER BY first_name DESC;

Select all rows from people table, order by age ascending:

SELECT * FROM people ORDER BY age ASC;

Select all rows from people table, order by age descending:

SELECT * FROM people ORDER BY age DESC;

Aggregation

Aggregation is another way to retrieve interesting information about our data. It will place table rows into groups that have the same values for the column you specify. Then you can perform data analysis on each of those groups

Divide all rows into groups by first_name. Show the SUM of the ages of each group. Also show what first_name each group has

SELECT SUM(age), first_name FROM people GROUP BY first_name;

Divide all rows into groups by first_name. Show the AVG of the ages of each group. Also show what first_name each group has

SELECT AVG(age), first_name FROM people GROUP BY first_name;

Divide all rows into groups by first_name. Show the MAX of the ages of each group. Also show what first_name each group has

SELECT MIN(age), first_name FROM people GROUP BY first_name;

Divide all rows into groups by first_name. Show the MIN of the ages of each group. Also show what first_name each group has

SELECT MAX(age), first_name FROM people GROUP BY first_name;

Divide all rows into groups by first_name. Show how many rows have a value in the age column. Also show what first_name each group has

SELECT COUNT(age), first_name FROM people GROUP BY first_name;

Divide all rows into groups by first_name. Show the number of rows in each group (how many rows have a value in any column). Also show what first_name each group has

SELECT COUNT(*), first_name FROM people GROUP BY first_name;

Divide all rows into groups by age. List the first_name values in each group and show what age each group has

SELECT array_agg(first_name), age FROM people GROUP BY age;

JOINS

You can combine tables horizontally

Append each row of the companies table onto the end of each row of the people table

SELECT * FROM people CROSS JOIN companies;

Do the same, but display only the rows where people.employer_id matches companies.id. Note that when you have multiple tables, you'll need to specify which table which column belongs to. Otherwise, as with the case of id, it could be ambiguous which table the column belongs to.

SELECT * FROM people JOIN companies ON people.employer_id = companies.id

Do the same as the previous example, but also display any rows from the people that were previously left off

SELECT * FROM people LEFT JOIN companies ON people.employer_id = companies.id

This is similar to LEFT JOIN but it displays any rows from the companies table that were previously left off

SELECT * FROM people RIGHT JOIN companies ON people.employer_id = companies.id ```

This is basically a combination of `LEFT JOIN` and `RIGHT JOIN`.  Display missing rows from *both* tables

```sql
SELECT * FROM people FULL OUTER JOIN companies ON people.employer_id = companies.id;

Combining Statments

You can combine WHERE, LIMIT, ORDER BY, OFFSET with your JOIN statements:

SELECT * 
FROM people 
LEFT JOIN companies 
	ON people.employer_id = companies.id
WHERE first_name LIKE 'M%' 
ORDER BY age ASC 
LIMIT 2 
OFFSET 1;

You can even add GROUP BY and use aggregation functions too:

SELECT AVG(age), first_name 
FROM people 
LEFT JOIN companies 
	ON people.employer_id = companies.id 
WHERE first_name LIKE 'M%' 
GROUP BY first_name 
ORDER BY avg ASC 
LIMIT 2 
OFFSET 1;

The order where you add these in the statement matters. The following breaks (GROUP BY must come before ORDER BY, LIMIT, OFFSET):

SELECT AVG(age), first_name 
FROM people 
LEFT JOIN companies 
	ON people.employer_id = companies.id 
WHERE first_name LIKE 'M%' 
ORDER BY avg ASC 
LIMIT 2 
OFFSET 1 
GROUP BY first_name;

If it breaks, just try reordering until it works. You can also research the order in which they need to come in the statement