Note that this does NOT make the column the the primary key column.
Example of inserting a row to courses:
INSERT INTO courses
('Intro to JavaScript');
Example of inserting a row to students:
INSERT INTO students
('Sally Smith', '1990-11-21');
Example of inserting a row to enrollments with nested queries:
INSERT INTO enrollments()
VALUES(
(SELECT student_id FROM students WHERE name = 'Sally Smith';),
(SELECT course_id FROM courses WHERE name = 'Intro to JavaScript';)
);
Get all students who are enrolled in 'Intro to JavaScript':
SELECT students.name AS student_name
FROM enrollments
JOIN students ON enrollments.student_id = students._id
JOIN courses ON enrollments.course_id = courses._id
WHERE courses.name = 'Intro to JavaScript';
Code-Along: Using Postgres in JavaScript
We're using a library called pg in order to interact with our Postgres database with JavaScript code.
Let's write a function that sends a query to the DB:
Note that the data we want are nested in the result.rows array.
result itself is a big object containing lots of metadata that we don't need at the moment.
Try-Catch Syntax
We attempt the operation in the try block.
If anything goes wrong, we catch and process the error in the catch block.
Write a function that takes in a planetName and finds that planet's residents.
We'll need to inject a parameter value into the query string.
const findPlanetResidents = async (planetName) => {
try {
const queryText = `
SELECT
people.name AS person_name,
people.mass,
people.height,
people.birth_year,
people.url,
people.homeworld
FROM people
JOIN planets
ON people.homeworld = planets._id
WHERE planets.name = ${planetName};
`;
const result = await db.query(queryText);
// This `if` conditional alerts us when there's no data from the query.
if (!results.rows.length) throw new Error('Expected results from query; received none.');
return results.rows;
}
catch (error) {
console.error(error);
}
};
If you see an error that says something like column "some_column" does not exist, it may be because you didn't wrap the injected value within single quotes.
`WHERE planets.name = '${planetName}';`
Write a function findXWhere
This is a highly reusable function that takes in tableName and whereClause and returns all the records from tableName that match the whereClause.
const findXWhere = (tableName, whereClause) => {
try {
const queryText = `
SELECT *
FROM ${tableName}
${whereClause}
`;
const result = await db.query(queryText);
if (!results.rows.length) throw new Error('Expected results from query; received none.');
return result.rows;
}
catch (error) {
console.error(error);
}
};
Example usage of the above function:
// Find all planets with arid climate
findXWhere('planets', `WHERE climate LIKE '%arid%'`);
// Find all info on episode 4 film
findXWhere('films', `WHERE episode_id = 4`);
Find the only other person who piloted the same ships:
try {
/* Previous code... */
const copilotQuery = `
SELECT
people.name AS person_name,
people.homeworld AS homeworld._id
FROM people_starships
JOIN people
ON people_starships.person_id = people._id
WHERE starship_id IN (5, 12)
ORDER BY person_id
`;
const copilotResults = await db.query(copilotQuery);
if (!copilotResults.rows.length) throw new Error('Expected results from query; received none.');
// Hardcode the results:
const twoTimeCopilotName = 'Chewbacca';
const twoTimeCopilotHomeworldId = 14;
}
Find the planet of the person we found above:
Also find the only other resident on that planet.
try {
const getPlanetNameQuery = `
SELECT
name
FROM planets
WHERE _id = ${twoTimeCopilotHomeworldId};
`;
// First find the planet name
const planetNameById = await db.query(getPlanetNameQuery);
const banditPlanetName = planetNameById[0].name;
// Second, find all residents of that planet
const allResidentsOfPlanet14 = await findPlanetResidents(banditPlanetName);
const banditName = allResidentsOfPlanet14.filter((resident) => {
return resident.person_name !== twoTimeCopilotName;
})[0].person_name;
}
Afternoon Group Exercise (Tell Me More)
General Pattern of the Async Functions
const asyncFuncToGetResultsFromDb = async () => {
try {
// Build your query text
// await the db.query with the query text and save the results in a constant
// Optional: print results to console to see the shape/contents of the results
// Return the results stored in .rows
}
catch (error) {
console.error(error);
}
};
// Call the function
Get each restaurant's review count:
SELECT restaurant_id, COUNT(*)
FROM reviews
GROUP BY restaurant_id
ORDER BY COUNT(*) desc;
Find the user who wrote the most reviews:
SELECT user_id, COUNT(*)
FROM reviews
-- Exclude users with invalid usernames
WHERE user_id != '#NAME?'
GROUP BY user_id
ORDER BY COUNT(*) desc
LIMIT 1;
Find all restaurants matching an ID:
SELECT * FROM restaurants
WHERE id = '${restaurantId}';
Get all reviews for a restaurant matchingn an ID:
SELECT * FROM reviews
WHERE restaurant_id = '${restaurantId}';
Insert a new review record into the reviews table and return the inserted record:
Morning Exercise Review
Creating Tables
Courses Table
Students Table
A column is by default optional if you don't specify it to be
NOT NULL
.dob
optional for thestudents
table.Enrollments Table
Add constraints to
enrollments
:students
table -- specifically the_id
column onstudents
table.courses
table -- specifically the_id
column.The
ADD CONSTRAINT
command is used to create a constraint after a table is already created.Sequential IDs
When inserting a new row, you either let Postgres create the sequential ID for you or insert your own unique ID.
You can specify a column type to be
SERIAL
.Note that this does NOT make the column the the primary key column.
Example of inserting a row to
courses
:Example of inserting a row to
students
:Example of inserting a row to
enrollments
with nested queries:Get all students who are enrolled in 'Intro to JavaScript':
Code-Along: Using Postgres in JavaScript
We're using a library called
pg
in order to interact with our Postgres database with JavaScript code.Let's write a function that sends a query to the DB:
Querying the DB is an asynchronous operation.
Note that the data we want are nested in the
result.rows
array.result
itself is a big object containing lots of metadata that we don't need at the moment.Try-Catch Syntax
We attempt the operation in the
try
block.If anything goes wrong, we catch and process the error in the
catch
block.Write a function that takes in a
planetName
and finds that planet's residents.We'll need to inject a parameter value into the query string.
If you see an error that says something like
column "some_column" does not exist
, it may be because you didn't wrap the injected value within single quotes.Write a function
findXWhere
This is a highly reusable function that takes in
tableName
andwhereClause
and returns all the records fromtableName
that match thewhereClause
.Example usage of the above function:
Capture the Bandit!
Find the only resident on Dathomir:
Find the person who matches the above target's mass and with the height of 180:
Find the ships piloted by the person we found above:
Find the only other person who piloted the same ships:
Afternoon Group Exercise (Tell Me More)
General Pattern of the Async Functions
Get each restaurant's review count:
Find the user who wrote the most reviews:
Find all restaurants matching an ID:
Get all reviews for a restaurant matchingn an ID:
Insert a new review record into the
reviews
table and return the inserted record:Find all reviews for restaurants matching a brand name:
Get most reviewed restaurant
Use the
getRestaurantsByReviewCount
function and get the top result.Then use
restaurantWithReviews
to find the reviews of this particular restaurant.