tacnode=> \d t1 Table "public.t1" Column | Type | Collation | Nullable | Default--------+--------------+----------+----------+-------------------------------------- id | integer | | not null | nextval('t1_id_seq'::text::regclass) name | text | | | age | smallint | | | gender | character(1) | | |Indexes: "t1_pkey" PRIMARY KEY, btree (id ASC)tacnode=> SELECT * FROM t1; id | name | age | gender----+------------+-----+-------- 1 | updatename | 11 | m 2 | testname | | 3 | updatename | 11 | f 4 | updatename | 11 | f 5 | testname4 | 22 | m 11 | updatename | 11 | f(6 rows)
Retrieve the data from the table that satisfies the given criteria.
tacnode=> SELECT * FROM t1 WHERE gender='m'; id | name | age | gender----+------------+-----+-------- 1 | updatename | 11 | m 5 | testname4 | 22 | m(2 rows)
Select specific fields to query
tacnode=> SELECT id, name FROM t1 WHERE gender='m'; id | name----+------------ 1 | updatename 5 | testname4(2 rows)
A subquery, an inner or nested query, is embedded within a PostgreSQL query and can be placed in a WHERE clause. It is utilized to return data that serves as a condition for the main query, helping to refine the data retrieval process. Subqueries can be employed with various statements, including SELECT, INSERT, UPDATE, and DELETE, as well as with operators such as =, <, >, <=, IN, and others.
Subqueries must adhere to these rules:
They need to be contained within parentheses.
A subquery should consist of only one column in the SELECT clause, unless the main query includes multiple columns for comparison with the subquery's selected column.
While ORDER BY cannot be utilized in a subquery, it can be applied in the main query, functioning similarly to GROUP BY in a subquery.
Subqueries that return multiple rows can only interact with various value operators, including IN, EXISTS, NOT IN, ANY / SOME, and ALL.
The BETWEEN operator is not allowable within a subquery, although it can be employed inside a subquery.
Subqueries are primarily utilized in SELECT statements, following this basic syntax:
The WITH query is an advanced SQL feature in PostgreSQL, commonly known as CTE (Common Table Expressions). This feature allows you to define an auxiliary statement within a complex query, similar to a temporary table created in the query. When dealing with intricate query statements, using WITH can significantly simplify the SQL, enhancing readability.
With Query syntax:
WITH regional_sales AS ( SELECT region, SUM(amount) AS total_sales FROM orders GROUP BY region), top_regions AS ( SELECT region FROM regional_sales WHERE total_sales > (SELECT SUM(total_sales)/10 FROM regional_sales))SELECT region, product, SUM(quantity) AS product_units, SUM(amount) AS product_salesFROM ordersWHERE region IN (SELECT region FROM top_regions)GROUP BY region, product;
Here’s a detailed example illustrating how to use the query. Below are the definitions and data for the test table:
tacnode=> \d t1 Table "public.t1" Column | Type | Collation | Nullable | Default--------+--------------+----------+----------+-------------------------------------- id | integer | | not null | nextval('t1_id_seq'::text::regclass) name | text | | | age | smallint | | | gender | character(1) | | |Indexes: "t1_pkey" PRIMARY KEY, btree (id ASC)tacnode=> SELECT * FROM t1; id | name | age | gender----+------------+-----+-------- 1 | updatename | 11 | m 2 | aa | 11 | m 3 | bb | 11 | m 4 | ee | 11 | f 5 | ff | 15 | f 6 | gg | 18 | m(6 rows)
USING With Query in SELECT.
tacnode=> WITH t AS (SELECT * FROM t1 WHERE gender='f') SELECT * FROM t WHERE age > 12; id | name | age | gender----+------+-----+-------- 5 | ff | 15 | f(1 row)
The DELETE command removes data from a table. You can target particular rows for deletion using the defined WHERE condition. If no WHERE condition is provided, all the data in the table will be deleted.
[ WITH [ RECURSIVE ] with_query [, ...] ]DELETE FROM [ ONLY ] table_name [ * ] [ [ AS ] alias ] [ USING from_item [, ...] ] [ WHERE condition | WHERE CURRENT OF cursor_name ] [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]
Refer to the DELETE documentation for additional usage syntax.
tacnode=> \d t2 Table "public.t2" Column | Type | Collation | Nullable | Default--------+--------------+----------+----------+----------------------------------------- id | integer | | not null | nextval('t1_id_seq'::regclass)::integer name | text | | | age | smallint | | | gender | character(1) | | |Indexes: "t2_pkey" PRIMARY KEY, btree (id ASC)tacnode=> select * from t2; id | name | age | gender----+------------+-----+-------- 10 | t2testname | 22 | f 11 | t2testname | 22 | f 12 | t2testname | 22 | f(3 rows)
Remove a record from the table.
-- Remove specific recordtacnode=> delete from t2 where id=11;DELETE 1tacnode=> select * from t2; id | name | age | gender----+------------+-----+-------- 10 | t2testname | 22 | f 12 | t2testname | 22 | f(2 rows)
Remove all data from the entire table.
-- Remove all datatacnode=> delete from t2;DELETE 2tacnode=> select * from t2; id | name | age | gender----+------+-----+--------(0 rows)
Utilize DELETE USING to reference other tables in a delete statement, streamlining complex delete operations that involve multiple tables in one SQL query.
-- Remove all products from the product table where quantity in stock is 0DELETE FROM productUSING stock WHERE product.id = stock.product_id AND stock.quantity = 0;
To enable multi-version concurrency control and TimeTravel features, MVCC attaches a timestamp to each record as a version marker. The deletion process does not instantly remove the old data from the disk. Instead, the old data is purged through asynchronous tasks only after the expired MVCC version. Consequently, storage space increases after a delete operation is performed but decreases once the asynchronous compaction is finished.
Perform an 'UPDATE' test using the table provided below.
tacnode=> \d t1 Table "public.t1" Column | Type | Collation | Nullable | Default--------+--------------+----------+----------+-------------------------------------- id | integer | | not null | nextval('t1_id_seq'::text::regclass) name | text | | | age | smallint | | | gender | character(1) | | |Indexes: "t1_pkey" PRIMARY KEY, btree (id ASC)tacnode=> select * from t1; id | name | age | gender----+------------+-----+-------- 1 | testname1 | 11 | m 2 | testname | | 3 | testname3 | 33 | f 4 | testname4 | 22 | f 5 | testname4 | 22 | m 11 | t2testname | 22 | f(6 rows)
Revise a row of data in the table.
tacnode=> update t1 set name='updatename' where id=1;UPDATE 1tacnode=> select * from t1 where id=1; id | name | age | gender----+------------+-----+-------- 1 | updatename | 11 | m(1 row)
Update multiple rows that fulfill the specified conditions.
tacnode=> select * from t1 where gender='f'; id | name | age | gender----+------------+-----+-------- 3 | testname3 | 33 | f 4 | testname4 | 22 | f 11 | t2testname | 22 | f(3 rows)tacnode=> update t1 set name='updatename',age=11 where gender='f';UPDATE 3tacnode=> select * from t1 where gender='f'; id | name | age | gender----+------------+-----+-------- 3 | updatename | 11 | f 4 | updatename | 11 | f 11 | updatename | 11 | f(3 rows)
To implement multi-version concurrency control and TimeTravel features, MVCC attaches timestamp information to each record as a version indicator. The update operation does not instantly remove the old data from the disk. Instead, the old data is purged through asynchronous tasks once the MVCC version expires. As a result, storage space increases following the execution of an update operation, and it only decreases after the asynchronous compaction is finalized.
The MERGE INTO statement allows you to combine records by integrating INSERT, UPDATE, and DELETE operations into a single command. It executes the appropriate actions depending on the matching conditions between the source and target tables. With MERGE INTO, you can efficiently maintain data consistency while synchronizing information across two tables.
Usage Scenarios
Data Warehouse ETL: Combine incremental data into data warehouse tables.
Data Synchronization: Align data across various systems or databases.
Data Deduplication: Remove duplicates and refresh data in a table according to defined criteria.
Syntax:
MERGE INTO target_table_name [[AS] target_alias]USING source_table_name [[AS] source_alias]ON ( condition )WHEN MATCHED THEN UPDATE SET column1 = value1 [, column2 = value2 ...]WHEN NOT MATCHED THEN INSERT (column1 [, column2 ...]) VALUES (value1 [, value2 ...]);
Parameters:
target_table_name: The table that will be updated or have data inserted into
source_table_name: The table that supplies the data
condition: Defines the matching criteria between the target and source tables
WHEN MATCHED THEN: Perform an UPDATE operation when the matching criteria is satisfied
WHEN NOT MATCHED THEN: Perform an INSERT operation when the matching criteria is not satisfied
MERGE INTO customers cUSING (SELECT * FROM new_customer_data) AS ncON c.id = nc.idWHEN MATCHED THEN UPDATE SET name = nc.name, email = nc.emailWHEN NOT MATCHED THEN INSERT (id, name, email) VALUES (nc.id, nc.name, nc.email);
For additional syntax regarding MERGE, refer to MERGE.
A view is fundamentally a stored query statement within a database. It functions as a virtual table without holding actual data. When we create a view, we assign it a name, allowing us to query it similarly to a table. A view does not exist physically, meaning a query executes each time the view is accessed. This approach is advantageous because it preserves only the query statement, alleviating the issues of constant data writing during frequent SQL calls.
Syntax:
CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] [ RECURSIVE ] VIEW name [ ( column_name< [, ...] ) ] [ WITH ( view_option_name [= view_option_value] [, ... ] ) ] AS query [ WITH [ CASCADED | LOCAL ] CHECK OPTION ]