PostgreSQL Basics 102 - Inserts Updates, Deletes and Selects
- Published on
- • 8 mins read•––– views
Before we start
If you don't have a database and a table already, where we talked about in the previous lesson Postgres basics
Here is a short summary, if you know what these commands do, great, keep reading this lesson, if not, make sure to read the first part.
CREATE DATABASE myroom
CREATE TABLE electronics (
id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
title VARCHAR (255) UNIQUE NOT NULL
);
ALTER TABLE electronics ADD COLUMN image VARCHAR (255);
ALTER TABLE electronics
ADD COLUMN type VARCHAR ( 255 ),
ADD COLUMN color VARCHAR ( 50 ) NOT NULL DEFAULT 'black';
Inserts
INSERT INTO electronics(
title, image, type)
VALUES (
'phone', 'phone.jpg', 'mobile'
);
You are free to organize the order of inserts
. However, make sure to follow the same order for the VALUES
command as well.
If you write title, image, type
in this order, then, follow the same order for the VALUES
.
Running this will confirm we have successfully inserted our data
select * from electronics
id | title | type | color | image
----+-------+--------+-------+-----------
1 | phone | mobile | black | phone.jpg
(1 row)
If you have noticed, I haven't declared anything for the "color" column. By default, Postgres will assign 'black'
since that's how it's setup via NOT NULL DEFAULT 'black';
Adding comments
You can use --
, to add comments.
INSERT INTO "electronics" (
"title", "image", "type" -- comment here
) VALUES (
'smart light', 'light.jpg', 'smart' -- homekit
);
If you noticed, we used double quotes (" "
) for title
, image
, and type
. Double quotes are optional, and you don't need to use them. On the other hand, using single quotes (' '
) for values
is required because they are strings (VARCHAR
).
To view the comments, we need to open the .sql
file, as they aren't stored inside the database. Running SELECT * FROM electronics
will not display our comments, but opening the .sql
file with a text editor will.
Inserting large data into existing table
Let's say, we found a table that we can use, and after checking it's content, it does math well with our own table. Great! Let's insert it to our table
INSERT INTO electronics (
title, image, type
) VALUES
( 'smartphone', 'smartphone.jpg', 'mobile' ),
( 'laptop', 'laptop.jpg', 'computer' ),
( 'monitor', 'monitor.jpg', 'display' ),
( 'keyboard', 'keyboard.jpg', 'input' ),
( 'mouse', 'mouse.jpg', 'input' ),
( 'speaker', 'speaker.jpg', 'audio' ),
ON CONFLICT DO NOTHING;
ON CONFLICT DO NOTHING
merges our existing table with the new insert
and does not throw an error for duplicates.
Let's say we had laptop
in our table before inserting the new dataset. Without ON CONFLICT DO NOTHING
, Postgres would throw an error, duplicate key value violates unique constraints
.
With ON CONFLICT DO NOTHING
in place, if there are duplicates of some keys, Postgres will simply skip them and insert the non-existing records into our table.
Updating with ON CONFLICT
If we want to update the picture of an entry,
INSERT INTO electronics (
title, image, type
) VALUES
( 'speaker', 'largeSpeaker.jpg', 'this won''t change' )
ON CONFLICT (title) DO UPDATE SET image = excluded.image;
We already have a speaker entry in our table. To replace its image, we can run this code ON CONFLICT (title) DO UPDATE SET image = excluded.image;
What it basically does is, if 'title' conflicts with another entry, change the image only. It will essentially update the image
and won't touch other properties.
Did you notice the double single quotes in the 'this won''t change'
part? Values
must be enclosed in single quotes. When we need to use a single quote within the value, we need to use two single quotes next to each other ''
.
and to check the updated value:
SELECT * FROM electronics where title = 'speaker';
// will return the table below.
id | title | image | type
----+------------+------------+-------
7 | speaker | largeSpeaker.jpg | audio
(1 row)
If we had a large inventory for a shop and not every product had an image, we could point all of them to a placeholder.jpg, and update it with help of the ON CONFLICT
. There are some useful ways to use ON CONFLICT
.
Another way to update:
UPDATE electronics SET image = 'default.jpg' WHERE title = 'speaker';
So, in another database, we could run this to replace images:
UPDATE inventory SET image = 'outOfStock.jpg' where stock = 0;
If you want to display changes right after updating them:
UPDATE electronics SET image = 'largeSpeaker.jpg' WHERE title = 'speaker' RETURNING id, title, image;
// will print this right after.
id | title | image
----+------------+----------------
7 | speaker | largeSpeaker.jpg
RETURNING
keyword with properties you want to view followed by will do that for you.
If you think that's too much typing, you could use *
for everything. Instead of typing RETURNING id, title, image
, you could use RETURNING *
Updating inserts
Let's add new values,
INSERT INTO electronics
(title, image)
VALUES
('place holder 1', 'palceH.jpg'),
('place holder 2', 'palceH.jpg');
and let's update them,
UPDATE electronics
SET image = 'noImage.jpg'
WHERE image = 'placeH.jpg'
RETURNING *;
// will return
id | title | image
----+------------+---------------
10 | place holder 1 | noImage.jpg
11 | place holder 2 | noImage.jpg
(2 rows)
This query updates the image
column in the electronics table, setting it to 'noImage.jpg' for all rows where the image column has a value of 'placeH.jpg'. It then returns all of the updated rows, because of *
.
If you know a coding language, this is about the same thing using Javascript.
for (let i = 0; i < imageArray.length; i++) {
if (imageArray[i] === 'placeH.jpg') {
imageArray[i] = 'noImage.jpg'
}
}
Deleting
This query will check electronics
table and delete entries with an image
with placeholder.jpg
as a value and return
(show) you the changes.
DELETE FROM electronics
WHERE image = 'placeholder.jpg'
RETURNING *;
Selects
Will return and display everything.
SELECT * FROM electronics
Will return id
and title
from electronics
SELECT id, title FROM electronics
When writing an application, it's crucial to select only the data you need. This not only helps you understand the purpose of a component when reviewing your code later but also improves performance by reducing payload size.
For instance, in a React component displaying first and last names, there's no need to retrieve unrelated information like images or addresses.
Think of it like packing for a trip: you wouldn't bring snow boots to Hawaii in July. Similarly, only select necessary data from your database. This approach keeps your code efficient and clear.
To limit the number of records you want to view, you can use LIMIT
.
SELECT id, title, image
FROM electronics
LIMIT 5;
Using LIMIT 5
returns the first 5 records. Implementing a LIMIT
is essential because some databases have millions or even billions of entries. Selecting all records without a limit may crash the servers.
To view the next 5 records, use OFFSET 5
.
SELECT id, title, image
FROM electronics
LIMIT 5
OFFSET 5;
Keep in mind that this approach might not work if the database is actively receiving or deleting entries. We'll discuss optimizing queries in more detail later on.
Better way to select and find entries is to use WHERE
SELECT id, title, type
FROM electronics
WHERE id > 13 limit 10;
Using WHERE
is better and more efficient. When you specify an id
and ask for 10 more items which id
greater than 13, Postgres can easily find that id
and show you the next 10 times. WHERE id >
allows to perform the same function with less calculations and resources.
We can also define a range with OR
SELECT *
FROM electronics
WHERE id <= 10
OR id >= 20;
You could also use AND
instead of OR
for similar reasons.
We can use <>
as the not keyword:
SELECT *
FROM electronics
WHERE type <> 'audio';
Will return and display everything with a title
different than audio
.
You shouldn't rely on the way Postgres returns the entries. Although it often orders values by their insertion order, the documentation states that this is not the required behavior
. Depending on the situation, Postgres might order entries by other standards
. Therefore, it's a good idea to ORDER
data the way you want it.
To order the results, you can use ORDER
BY like this:
SELECT * FROM electronics ORDER BY title;
If we need the reverse order, keyword DESC
can help us.
SELECT * FROM electronics ORDER BY id DESC;