{"id":21180720,"url":"https://github.com/islamsamy214/learning-pgsql","last_synced_at":"2025-09-12T23:33:16.601Z","repository":{"id":262598977,"uuid":"879564172","full_name":"islamsamy214/learning-pgsql","owner":"islamsamy214","description":"Learning PostgreSQL: A Comprehensive Cheat Sheet","archived":false,"fork":false,"pushed_at":"2024-11-13T08:59:32.000Z","size":168,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-21T12:11:17.210Z","etag":null,"topics":["cheatsheet","cte","data-management","database","database-schema","index","postgresql","queries","rds","relational-databases","sql","transaction","tutorial","views"],"latest_commit_sha":null,"homepage":"","language":"PLpgSQL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"cc0-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/islamsamy214.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-28T06:28:34.000Z","updated_at":"2024-11-13T08:59:35.000Z","dependencies_parsed_at":"2024-11-13T09:48:58.231Z","dependency_job_id":null,"html_url":"https://github.com/islamsamy214/learning-pgsql","commit_stats":null,"previous_names":["islamsamy214/learning-pgsql"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/islamsamy214%2Flearning-pgsql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/islamsamy214%2Flearning-pgsql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/islamsamy214%2Flearning-pgsql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/islamsamy214%2Flearning-pgsql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/islamsamy214","download_url":"https://codeload.github.com/islamsamy214/learning-pgsql/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243632407,"owners_count":20322382,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cheatsheet","cte","data-management","database","database-schema","index","postgresql","queries","rds","relational-databases","sql","transaction","tutorial","views"],"created_at":"2024-11-20T17:45:59.972Z","updated_at":"2025-03-14T19:19:32.510Z","avatar_url":"https://github.com/islamsamy214.png","language":"PLpgSQL","readme":"# learning-pgsql\n\nThis repository contains the notes I took while learning PostgreSQL.\n\n## Table of Contents\n\n- [Create Database](#create-database)\n- [Create Table](#create-table)\n- [Insert Data](#insert-data)\n- [Fetch Data](#fetch-data)\n- [Filter Data](#filter-data)\n- [Update Data](#update-data)\n- [Delete Data](#delete-data)\n- [Aggregate Functions](#aggregate-functions)\n- [Group Data](#group-data)\n- [Order Data](#order-data)\n- [Joining Tables](#joining-tables)\n- [Pagination](#pagination)\n- [Unions](#unions)\n- [Intersections](#intersections)\n- [Differences](#differences)\n- [Subqueries](#subqueries)\n- [Indexes](#indexes)\n- [Benchmarks](#benchmarks)\n- [Common Table Expressions](#common-table-expressions)\n- [Recursive Common Table Expressions](#recursive-common-table-expressions)\n- [Views](#views)\n- [Materialized Views](#materialized-views)\n- [Transactions](#transactions)\n- [Schema](#schema)\n\n## Create Database\n\nIn PostgreSQL, **templates** are predefined databases used as starting points when creating new databases. They provide a structure and initial setup that can be cloned into a new database. PostgreSQL comes with two default templates: `template1` and `template0`.\n\nIn summary, `template1` is the default template for creating new databases, while `template0` is a clean, unmodifiable template that can be used to create databases with specific settings.\n\n### Template1\n\n- `template1` is the default template that PostgreSQL uses to create new databases if no template is specified.\n- It contains some default objects and settings that can be customized by the PostgreSQL user. Any changes made to `template1` (such as adding extensions, functions, or custom settings) will be cloned into any new databases created using it.\n- Since it’s modifiable, if you install extensions or add custom settings to `template1`, these will automatically be included in all databases created from it.\n\n### Template0\n\n- `template0` is a \"pristine\" template, containing only the bare essentials and no custom configurations.\n- It is useful when you want to create a database with specific settings, such as custom encoding or collation, because it doesn’t enforce existing settings.\n- `template0` is unmodifiable to ensure it remains in its original, clean state. This makes it ideal when you need to set a specific collation or encoding that might differ from `template1`.\n\nWhen creating a new database, you can specify a template as follows:\n\n```sql\nCREATE DATABASE my_database TEMPLATE template0;\n```\n\nOr use `template1` explicitly (though it’s the default):\n\n```sql\nCREATE DATABASE my_database TEMPLATE template1;\n```\n\nBy choosing `template0`, you have more flexibility with encoding and collation settings, especially in cases where `template1` imposes a default setting that might be incompatible with what you need.\n\n## Create Table\n\nTo create a new table in PostgreSQL, you use the `CREATE TABLE` statement. The following illustrates the basic syntax of the `CREATE TABLE` statement:\n\n```sql\nCREATE TABLE table_name (\n    column1 datatype,\n    column2 datatype,\n    column3 datatype,\n    ...\n);\n```\n\nIn this syntax:\ncolumn1, column2, column3, … are the names of the columns of the table.\ndatatype is the type of data that the column can hold such as integer, character, decimal, etc.\ntable_name is the name of the table that the new table will belong to.\n\n### Data types\n\nPostgreSQL provides several data types that allow you to define columns of tables:\nVARCHAR(n): A variable-length character string with a maximum size of n characters.\nTEXT: A variable-length character string with no maximum limit.\nCHAR(n): A fixed-length character string with a size of n characters.\nINTEGER: A signed four-byte integer.\nDECIMAL: An exact numeric value with a fixed number of digits on both the whole and the fractional parts.\nNUMERIC: An exact numeric value with a user-specified precision and scale.\nDATE: A date value in the format YYYY-MM-DD.\nTIME: A time value in the format HH:MI:SS.\nTIMESTAMP: A date and time value in the format YYYY-MM-DD HH:MI:SS.\nBOOLEAN: A true or false value.\nSERIAL: An auto-incrementing four-byte integer.\nIn addition to the basic data types, PostgreSQL provides several special-purpose data types such as geometric, network address, and monetary data types.\nREAL: A single-precision floating-point number, it just caring about the 6 digits after the decimal point to be percise, if more than that, it will work aROUND it.\n\n### Constraints\n\nConstraints are rules that enforce the integrity of the data stored in the table. PostgreSQL provides several types of constraints that you can add to a table:\n\n- `NOT NULL`: Ensures that a column cannot have a NULL value.\n- `UNIQUE`: Ensures that all values in a column are unique, if you used it like this `UNIQUE (column1, column2, …)`, it will ensure that the combination of values in the specified columns is unique.\n- `PRIMARY KEY`: A combination of `NOT NULL` and `UNIQUE`. It uniquely identifies each row in a table.\n- `FOREIGN KEY`: Ensures that the values in a column match the values in another table’s column.\n- `CHECK`: Ensures that all values in a column satisfy a specified condition, it works with operators like `=`, `\u003e`, `\u003c`, `\u003e=`, `\u003c=`, `\u003c\u003e`, `BETWEEN`, `LIKE`, `IN`, and `IS NULL`.\n- `DEFAULT`: Provides a default value for a column when no value is specified.\n- `INDEX`: Improves the performance of queries by allowing them to retrieve data more quickly.\n\n### On Delete/Update Options\n\nWhen you define a foreign key constraint, you can specify the `ON DELETE` and `ON UPDATE` options to define the action that the database should take when a referenced row is deleted or updated. The following options are available:\n\n- `CASCADE`: Deletes or updates the rows in the child table when the referenced row is deleted or updated.\n- `SET NULL`: Sets the foreign key column in the child table to NULL when the referenced row is deleted or updated.\n- `RESTRICT`: Prevents the deletion or update of the referenced row if there are any related rows in the child table.\n- `NO ACTION`: The same as `RESTRICT`. It prevents the deletion or update of the referenced row if there are any related rows in the child table.\n\nHere’s an example that creates a foreign key constraint with the `ON DELETE CASCADE` option:\n\n```sql\nCREATE TABLE orders (\n    order_id SERIAL PRIMARY KEY,\n    product_id INTEGER,\n    quantity INTEGER,\n    FOREIGN KEY (product_id)\n        REFERENCES products (product_id)\n        ON DELETE CASCADE\n);\n```\n\nIn this example, the `ON DELETE CASCADE` option specifies that when a row in the `products` table is deleted, all related rows in the `orders` table will also be deleted.\n\n## Insert Data\n\nTo insert data into a table in PostgreSQL, you use the `INSERT INTO` statement. The following illustrates the syntax of the `INSERT INTO` statement:\n\n```sql\nINSERT INTO table_name (column1, column2, column3, …)\nVALUES (value1, value2, value3, …);\n```\n\nbtw, you can insert multiple rows into a table with a single `INSERT` statement as follows:\n\n```sql\nINSERT INTO table_name (column1, column2, column3, …)\nVALUES\n    (value1, value2, value3, …),\n    (value4, value5, value6, …),\n    …;\n```\n\nyou can also insert from another table as follows:\n\n```sql\nINSERT INTO table_name (column1, column2, column3, …)\nSELECT column1, column2, column3, …\nFROM another_table\nWHERE condition;\n``` \n\n## Fetch Data\n\nTo query data from a table in PostgreSQL, you use the `SELECT` statement. The following illustrates the basic syntax of the `SELECT` statement:\n\n```sql\nSELECT\n    column1,\n    column2,\n    ...\nFROM\n    table_name;\n```\n\nIn this syntax:\n\n- column1, column2, … are the columns of the table that you want to retrieve data from.\n- table_name is the name of the table that you want to query data from.\n\nIf you want to retrieve data from all columns of the table, you use the following syntax:\n\n```sql\nSELECT * FROM table_name;\n```\n\nIn this syntax, the asterisk (\\*) is a wildcard character that represents all columns of the table.\n\n### Math Operators\n\nYou can use the following math operators in the `SELECT` statement to perform arithmetic operations:\n\n- `+` for addition\n- `-` for subtraction\n- `*` for multiplication\n- `/` for division\n- `%` for modulor\n- `^` for exponentiation\n- `|/` for square root\n- `||/` for cube root\n- `!!` for factorial\n- `@` for absolute value\n- `||` for concatenation\n\n### String Functions\n\nPostgreSQL provides a variety of string functions that allow you to manipulate strings. Here are some common string functions:\n\n- `LENGTH(string)`: Returns the length of the string.\n- `UPPER(string)`: Converts the string to uppercase.\n- `LOWER(string)`: Converts the string to lowercase.\n- `TRIM([leading|trailing|both] [characters] from string)`: Removes the specified characters from the beginning, end, or both ends of the string.\n- `POSITION(substring IN string)`: Returns the position of the substring in the string.\n- `SUBSTRING(string FROM start [FOR length])`: Extracts a substring from the string.\n- `CONCAT(string1, string2)`: Concatenates two strings.\n\n### Math Functions\n\nPostgreSQL provides a variety of math functions that allow you to perform mathematical operations. Here are some common math functions:\n\n- `ABS(number)`: Returns the absolute value of the number.\n- `CEIL(number)`: Returns the smallest integer greater than or equal to the number.\n- `FLOOR(number)`: Returns the largest integer less than or equal to the number.\n- `ROUND(number, decimal_places)`: Rounds the number to the specified number of decimal places.\n- `SQRT(number)`: Returns the square root of the number.\n- `CBRT(number)`: Returns the cube root of the number.\n- `POWER(base, exponent)`: Returns the base raised to the exponent.\n- `MOD(dividend, divisor)`: Returns the remainder of the division of the dividend by the divisor.\n- `RANDOM()`: Returns a random number between 0 and 1.\n- `TRUNC(number, decimal_places)`: Truncates the number to the specified number of decimal places.\n- `GREATEST(value1, value2, …)`: Returns the greatest value from a list of values.\n- `LEAST(value1, value2, …)`: Returns the least value from a list of values.\n\n## Filter Data\n\nTo filter data in PostgreSQL, you use the `WHERE` clause in the `SELECT` statement. The following illustrates the basic syntax of the `SELECT` statement with the `WHERE` clause:\n\n```sql\nSELECT\n    column1,\n    column2,\n    ...\nFROM\n    table_name\nWHERE\n    condition;\n```\n\nIn this syntax:\n\n- column1, column2, … are the columns of the table that you want to retrieve data from.\n- table_name is the name of the table that you want to query data from.\n- condition is a boolean expression that evaluates to true or false.\n\nThe `WHERE` clause allows you to filter rows based on a specified condition. If the condition evaluates to true, the row is included in the result set; otherwise, it is excluded.\n\n### Comparison Operators\n\nPostgreSQL provides a variety of comparison operators that allow you to compare values. Here are some common comparison operators:\n\n- `=`: Equal to\n- `\u003c\u003e` or `!=`: Not equal to\n- `\u003e`: Greater than\n- `\u003c`: Less than\n- `\u003e=`: Greater than or equal to\n- `\u003c=`: Less than or equal to\n- `BETWEEN`: Between an inclusive range\n- `IN`: In a specified list\n- `NOT IN`: Not in a specified list\n- `LIKE`: Similar to a specified pattern\n- `ILIKE`: Case-insensitive version of `LIKE`\n- `IS NULL`: Is a null value\n- `IS NOT NULL`: Is not a null value\n- `IS DISTINCT FROM`: Is distinct from a specified value\n- `IS NOT DISTINCT FROM`: Is not distinct from a specified value\n- `ANY` or `SOME`: Compares a value to any value in a list\n- `ALL`: Compares a value to all values in a list\n\n### Logical Operators\n\nPostgreSQL provides several logical operators that allow you to combine multiple conditions. Here are some common logical operators:\n\n- `AND`: Returns true if both conditions are true\n- `OR`: Returns true if either condition is true\n- `NOT`: Returns true if the condition is false\n\n### Case Expression\n\nThe `CASE` expression allows you to add conditional logic to a query. It evaluates a list of conditions and returns one of multiple possible result expressions. The following illustrates the basic syntax of the `CASE` expression:\n\n```sql\nCASE\n    WHEN condition1 THEN result1\n    WHEN condition2 THEN result2\n    ...\n    ELSE result\nEND\n```\n\nIn this syntax:\n\n- condition1, condition2, … are the conditions that you want to evaluate.\n- result1, result2, … are the result expressions that you want to return.\n- result is the default result expression if none of the conditions are true.\n\n## Update Data\n\nTo update data in a table in PostgreSQL, you use the `UPDATE` statement. The following illustrates the basic syntax of the `UPDATE` statement:\n\n```sql\nUPDATE table_name\nSET column1 = value1,\n    column2 = value2,\n    ...\nWHERE condition;\n```\n\nIn this syntax:\n\n- table_name is the name of the table that you want to update data in.\n- column1, column2, … are the columns that you want to update.\n- value1, value2, … are the new values that you want to set for the columns.\n\n## Delete Data\n\nTo delete data from a table in PostgreSQL, you use the `DELETE` statement. The following illustrates the basic syntax of the `DELETE` statement:\n\n```sql\nDELETE FROM table_name\nWHERE condition;\n```\n\nIn this syntax:\n\n- table_name is the name of the table that you want to delete data from.\n- condition is a boolean expression that evaluates to true or false.\n\nThe `DELETE` statement deletes all rows from the table that satisfy the condition. If you omit the `WHERE` clause, the `DELETE` statement will delete all rows from the table.\n\n## Aggregate Functions\n\nPostgreSQL provides a variety of aggregate functions that allow you to perform calculations on a set of values. Here are some common aggregate functions:\n\n- `COUNT()`: Returns the number of rows in a group.\n- `SUM()`: Returns the sum of values in a group.\n- `AVG()`: Returns the average of values in a group.\n- `MIN()`: Returns the minimum value in a group.\n- `MAX()`: Returns the maximum value in a group.\n\nYou can use aggregate functions in the `SELECT` statement to calculate summary statistics for a group of rows. Here’s an example that calculates the total number of employees in the `employees` table:\n\n```sql\nSELECT COUNT(*) AS total_employees\nFROM employees;\n```\n\nIn this example, the `COUNT()` function calculates the total number of rows in the `employees` table. The `AS` keyword is used to alias the result of the aggregate function as `total_employees`.\n\n## Group Data\n\nTo group data in PostgreSQL, you use the `GROUP BY` clause in the `SELECT` statement. The `GROUP BY` clause divides the rows returned by the `SELECT` statement into groups. The following illustrates the basic syntax of the `SELECT` statement with the `GROUP BY` clause:\n\n```sql\nSELECT\n    column1,\n    aggregate_function(column2)\nFROM\n    table_name\nGROUP BY\n    column1;\n```\n\nIn this syntax:\n\n- column1 is the column that you want to group by.\n- aggregate_function(column2) is an aggregate function that calculates summary statistics for each group.\n- table_name is the name of the table that you want to query data from.\n\nThe `GROUP BY` clause divides the rows returned by the `SELECT` statement into groups based on the values in the specified column. The aggregate function calculates summary statistics for each group.\n\n### HAVING Clause\n\nThe `HAVING` clause allows you to filter groups based on a specified condition. The following illustrates the basic syntax of the `SELECT` statement with the `GROUP BY` and `HAVING` clauses:\n\n```sql\nSELECT\n    column1,\n    aggregate_function(column2)\nFROM\n    table_name\nGROUP BY\n    column1\nHAVING\n    condition;\n```\n\nIn this syntax:\n\n- column1 is the column that you want to group by.\n- aggregate_function(column2) is an aggregate function that calculates summary statistics for each group.\n- table_name is the name of the table that you want to query data from.\n- condition is a boolean expression that evaluates to true or false.\n\nThe `HAVING` clause filters groups based on a specified condition. If the condition evaluates to true, the group is included in the result set; otherwise, it is excluded.\n\n## Order Data\n\nTo order data in PostgreSQL, you use the `ORDER BY` clause in the `SELECT` statement. The `ORDER BY` clause sorts the rows returned by the `SELECT` statement. The following illustrates the basic syntax of the `SELECT` statement with the `ORDER BY` clause:\n\n```sql\nSELECT\n    column1,\n    column2,\n    ...\nFROM\n    table_name\nORDER BY\n    column1 [ASC|DESC],\n    column2 [ASC|DESC],\n    ...;\n```\n\nIn this syntax:\n\n- column1, column2, … are the columns that you want to sort by, it will sort by the first column first, then the second column, and so on.\n- table_name is the name of the table that you want to query data from.\n- ASC is the ascending order (default).\n- DESC is the descending order.\n\n## Joining Tables\n\nIn PostgreSQL, you can join two or more tables to query data from multiple tables. The following illustrates the basic syntax of the `SELECT` statement with the `JOIN` clause:\n\n```sql\nSELECT\n    column1,\n    column2,\n    ...\nFROM\n    table1\nJOIN\n    table2 ON table1.column_name = table2.column_name;\n```\n\nIn this syntax:\n\n- table1, table2 are the names of the tables that you want to join.\n- column1, column2, … are the columns that you want to retrieve data from.\n- column_name is the column that you want to join the tables on.\n\n### Types of Joins\n\nPostgreSQL supports several types of joins that allow you to combine rows from two or more tables. Here are some common types of joins:\n\n- `INNER JOIN` or `JOIN`: Returns rows when there is a match in both tables.\n- `LEFT JOIN` or `LEFT OUTER JOIN`: Returns all rows from the left table and the matched rows from the right table.\n- `RIGHT JOIN` or `RIGHT OUTER JOIN`: Returns all rows from the right table and the matched rows from the left table.\n- `FULL JOIN` or `FULL OUTER JOIN`: Returns rows when there is a match in one of the tables.\n\n## Pagination\n\nTo limit the number of rows returned by a query in PostgreSQL, you use the `LIMIT` clause. The `LIMIT` clause is typically used with the `ORDER BY` clause to sort the rows before limiting the number of rows returned. The following illustrates the basic syntax of the `SELECT` statement with the `LIMIT` clause:\n\n```sql\nSELECT\n    column1,\n    column2,\n    ...\nFROM\n    table_name\nORDER BY\n    column1\nLIMIT\n    row_count\nOFFSET\n    offset;\n```\n\nIn this syntax:\n\n- column1, column2, … are the columns that you want to retrieve data from.\n- table_name is the name of the table that you want to query data from.\n- row_count is the maximum number of rows to return.\n- offset is the number of rows to skip before starting to return rows.\n\nThe `LIMIT` clause allows you to limit the number of rows returned by a query. The `OFFSET` clause allows you to skip a specified number of rows before starting to return rows.\n\n## Unions\n\nIn PostgreSQL, you can combine the results of two or more queries using the `UNION` operator. The `UNION` operator removes duplicate rows from the result set. The following illustrates the basic syntax of the `UNION` operator:\n\n```sql\nSELECT\n    column1,\n    column2,\n    ...\nFROM\n    table1\nUNION -- or `UNION ALL` to keep duplicates\nSELECT\n    column1,\n    column2,\n    ...\nFROM\n    table2;\n```\n\nIn this syntax:\n\n- column1, column2, … are the columns that you want to retrieve data from.\n- table1, table2 are the names of the tables that you want to query data from.\n- `UNION` removes duplicate rows from the result set.\n- `UNION ALL` keeps duplicate rows in the result set.\n- The number of columns and their data types must match in all queries.\n\nThe `UNION` operator allows you to combine the results of two or more queries into a single result set. The `UNION ALL` operator allows you to combine the results of two or more queries into a single result set, including duplicate rows.\n\n## Intersections\n\nIn PostgreSQL, you can find the intersection of two or more queries using the `INTERSECT` operator. The `INTERSECT` operator returns rows that are common to all queries. The following illustrates the basic syntax of the `INTERSECT` operator:\n\n```sql\nSELECT\n    column1,\n    column2,\n    ...\nFROM\n    table1\nINTERSECT -- or `INTERSECT ALL` to keep duplicates\nSELECT\n    column1,\n    column2,\n    ...\nFROM\n    table2;\n```\n\nIn this syntax:\n\n- column1, column2, … are the columns that you want to retrieve data from.\n- table1, table2 are the names of the tables that you want to query data from.\n- The number of columns and their data types must match in all queries.\n\nThe `INTERSECT` operator allows you to find the intersection of two or more queries. It returns rows that are common to all queries.\n\n## Differences\n\nIn PostgreSQL, you can find the difference between two or more queries using the `EXCEPT` operator. The `EXCEPT` operator returns rows that are in the first query but not in the second query. The following illustrates the basic syntax of the `EXCEPT` operator:\n\n```sql\nSELECT\n    column1,\n    column2,\n    ...\nFROM\n    table1\nEXCEPT -- or `EXCEPT ALL` to keep duplicates\nSELECT\n    column1,\n    column2,\n    ...\nFROM\ntable2;\n```\n\nIn this syntax:\n\n- column1, column2, … are the columns that you want to retrieve data from.\n- table1, table2 are the names of the tables that you want to query data from.\n- The number of columns and their data types must match in all queries.\n\nThe `EXCEPT` operator allows you to find the difference between two or more queries. It returns rows that are in the first query but not in the second query.\n\n## Subqueries\n\nIn PostgreSQL, you can nest one query inside another query to perform more complex queries. A query that contains another query is called a subquery. The following illustrates the basic syntax of a subquery:\n\n```sql\nSELECT\n    column1,\n    column2,\n    ...\nFROM\n    table_name\nWHERE\n    column1 IN (SELECT column1 FROM table_name WHERE condition);\n```\n\nIn this syntax:\n\n- column1, column2, … are the columns that you want to retrieve data from.\n- table_name is the name of the table that you want to query data from.\n- condition is a boolean expression that evaluates to true or false.\n\n## Indexes\n\nIn PostgreSQL, an index is a data structure that improves the speed of data retrieval operations on a table. Indexes are used to quickly locate data without having to search every row in a table. The following illustrates the basic syntax of creating an index:\n\n```sql\nCREATE INDEX index_name\nON table_name (column1, column2, ...);\n```\n\nIn this syntax:\n\n- index_name is the name of the index.\n- table_name is the name of the table that the index will be created on.\n- column1, column2, … are the columns that the index will be created on.\n\nIndexes can be created on one or more columns of a table. When you create an index on a column, PostgreSQL creates a separate data structure that stores the values of that column in sorted order. This allows PostgreSQL to quickly locate rows based on the values in the indexed column.\n\nNOTICE: PostgreSQL automatically creates an index for the `primary key` and `unique` constraints columns of a table. You can also create indexes manually to improve the performance of queries that filter, sort, or join data.\n\n## Benchmarks\n\nIn PostgreSQL, you can use the `EXPLAIN` statement to analyze the execution plan of a query. The `EXPLAIN` statement shows how PostgreSQL will execute a query, including the order in which tables will be accessed and the types of joins that will be used. The following illustrates the basic syntax of the `EXPLAIN` statement:\n\n```sql\nEXPLAIN ANALYSE SELECT\n    column1,\n    column2,\n    ...\nFROM\n    table_name\nWHERE\n    condition;\n```\n\nIn this syntax:\n\n- column1, column2, … are the columns that you want to retrieve data from.\n- table_name is the name of the table that you want to query data from.\n- condition is a boolean expression that evaluates to true or false.\n\nThe `EXPLAIN` statement provides valuable information about how PostgreSQL will execute a query. It can help you identify performance bottlenecks and optimize your queries for better performance.\n\nThe `ANALYSE` option tells PostgreSQL to actually execute the query and provide detailed performance statistics. This can help you identify slow queries and optimize them for better performance.\n\n## Common Table Expressions \n\nIn PostgreSQL, you can use common table expressions (CTEs) to define temporary result sets that can be used in subsequent queries. CTEs are useful for breaking down complex queries into smaller, more manageable parts. The following illustrates the basic syntax of a CTE:\n\n```sql\nWITH cte_name AS (\n    SELECT\n        column1,\n        column2,\n        ...\n    FROM\n        table_name\n    WHERE\n        condition\n)\nSELECT\n    column1,\n    column2,\n    ...\nFROM\n    cte_name;\n```\n\nIn this syntax:\n\n- cte_name is the name of the common table expression.\n- column1, column2, … are the columns that you want to retrieve data from.\n- table_name is the name of the table that you want to query data from.\n- condition is a boolean expression that evaluates to true or false.\n\nCTEs allow you to define temporary result sets that can be used in subsequent queries. They are useful for breaking down complex queries into smaller, more manageable parts.\n\n## Recursive Common Table Expressions\n\nIn PostgreSQL, you can use recursive common table expressions (CTEs) to define recursive queries that reference themselves. Recursive CTEs are useful for querying hierarchical data structures, such as organization charts or bill of materials. The following illustrates the basic syntax of a recursive CTE:\n\n```sql\nWITH RECURSIVE cte_name AS (\n    SELECT\n        column1,\n        column2,\n        ...\n    FROM\n        table_name\n    WHERE\n        condition\n    UNION ALL\n    SELECT\n        column1,\n        column2,\n        ...\n    FROM\n        cte_name\n    WHERE\n        condition\n)\nSELECT\n    column1,\n    column2,\n    ...\nFROM\n    cte_name;\n```\n\nIn this syntax:\n\n- cte_name is the name of the recursive common table expression.\n- column1, column2, … are the columns that you want to retrieve data from.\n- table_name is the name of the table that you want to query data from.\n- condition is a boolean expression that evaluates to true or false.\n\nRecursive CTEs allow you to define recursive queries that reference themselves. They are useful for querying hierarchical data structures, such as organization charts or bill of materials.\n\n## Views\n\nIn PostgreSQL, a view is a virtual table that is based on the result of a query. Views allow you to encapsulate complex queries and reuse them in other queries. The following illustrates the basic syntax of creating a view:\n\n```sql\nCREATE VIEW view_name AS\nSELECT\n    column1,\n    column2,\n    ...\nFROM\n    table_name\nWHERE\n    condition;\n```\n\nIn this syntax:\n\n- view_name is the name of the view.\n- column1, column2, … are the columns that you want to retrieve data from.\n- table_name is the name of the table that you want to query data from.\n- condition is a boolean expression that evaluates to true or false.\n\nViews allow you to encapsulate complex queries and reuse them in other queries. They are useful for simplifying queries and improving performance by precomputing results.\n\n## Materialized Views\n\nIn PostgreSQL, a materialized view is a physical copy of the result of a query that is stored on disk. Materialized views are useful for improving the performance of queries that involve complex calculations or aggregations. The following illustrates the basic \n\nThink of a materialized view as a cache for the result of a query. When you create a materialized view, PostgreSQL executes the query and stores the result on disk. Subsequent queries can then retrieve the result from the materialized view instead of re-executing the query.\n\nsyntax of creating a materialized view:\n\n```sql\nCREATE MATERIALIZED VIEW view_name AS\nSELECT\n    column1,\n    column2,\n    ...\nFROM\n    table_name\nWHERE\n    condition;\n```\n\nIn this syntax:\n\n- view_name is the name of the materialized view.\n- column1, column2, … are the columns that you want to retrieve data from.\n- table_name is the name of the table that you want to query data from.\n- condition is a boolean expression that evaluates to true or false.\n\nAnd to refresh the materialized view, you can use the `REFRESH MATERIALIZED VIEW` statement:\n\n```sql\nREFRESH MATERIALIZED VIEW view_name;\n```\n\nMaterialized views are useful for improving the performance of queries that involve complex calculations or aggregations. They can help reduce the time it takes to execute queries by precomputing results and storing them on disk.\n\n## Transactions\n\nIn PostgreSQL, a transaction is a sequence of one or more SQL statements that are executed as a single unit of work. Transactions allow you to group multiple statements together and ensure that they are executed atomically. The following illustrates the basic syntax of a transaction:\n\n```sql\nBEGIN;\n-- SQL statements\nCOMMIT;\n```\n\nIn this syntax:\n\n- `BEGIN` starts a new transaction.\n- `COMMIT` commits the transaction and makes the changes permanent.\n\nTransactions allow you to group multiple statements together and ensure that they are executed atomically. If any statement in the transaction fails, the entire transaction is rolled back, and the changes are discarded.\n\nIf you want to discard the changes made in a transaction, you can use the `ROLLBACK` statement:\n\n```sql\nBEGIN;\n-- SQL statements\nROLLBACK;\n```\n\nThe `ROLLBACK` statement discards the changes made in the transaction and rolls back to the beginning of the transaction.\n\n## Schema\n\nIn PostgreSQL, a schema is a namespace that contains named database objects, such as tables, views, indexes, and sequences. Schemas allow you to organize database objects into logical groups and avoid naming conflicts. The following illustrates the basic syntax of creating a schema:\n\n```sql\nCREATE SCHEMA schema_name;\n```\n\nIn this syntax:\n\n- schema_name is the name of the schema.\n\nYou can create a table in a specific schema by specifying the schema name in the `CREATE TABLE` statement:\n\n```sql\nCREATE TABLE schema_name.table_name (\n    column1 datatype,\n    column2 datatype,\n    ...\n);\n```\n\nIn this syntax:\n\n- schema_name is the name of the schema.\n- table_name is the name of the table.\n\nSchemas allow you to organize database objects into logical groups and avoid naming conflicts. They are useful for managing large databases with many tables, views, and other objects.\n\nYou can also set the default schema for a user by using the `ALTER ROLE` statement:\n\n```sql\nALTER ROLE username SET search_path TO schema_name;\n```\n\nTo make sure which schema you are currently in, you can use the following query:\n\n```sql\nSELECT current_schema();\n```\n\nTo determine the default schema for executing queries, you can use the following query:\n\n```sql\nSHOW search_path;\n```\n\nTo change the default schema for executing queries, you can use the following query:\n\n```sql\nSET search_path TO \"$user\",schema_name;\n```\n\nTo undo the changes made to the default schema for executing queries, you can use the following query:\n\n```sql\nRESET search_path;\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fislamsamy214%2Flearning-pgsql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fislamsamy214%2Flearning-pgsql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fislamsamy214%2Flearning-pgsql/lists"}