psql base
注意:这不是一个基础文档
从零开始-> visit: https://www.postgresqltutorial.com
安装
step0
https://www.postgresqltutorial.com/postgresql-getting-started/load-postgresql-sample-database/
https://juejin.cn/post/7219953605762875453
step1
brew install libpq
step2
由于 libpq 是 keg-only,Homebrew 不会自动将其链接到 /opt/homebrew/bin 目录中,这是为了避免与 postgresql 公式(formula)发生冲突。在这种情况下,如果你想要在任何地方都能使用 libpq 提供的命令(比如 psql),你需要手动将其可执行文件的路径添加到你的 PATH 环境变量中。
根据 Homebrew 提示的操作,你可以通过以下命令将 libpq 的 bin 目录添加到 PATH 中:
echo 'export PATH="/opt/homebrew/opt/libpq/bin:$PATH"' >> ~/.zshrc
这个命令会将一行添加到你的 ~/.zshrc 文件中(假设你使用的是默认的 zsh shell),这行内容会将 libpq 的 bin 目录添加到你的 PATH 环境变量中。添加这行之后,你需要重新加载 ~/.zshrc 文件或者重启终端来使更改生效。
要立即应用更改,你可以运行以下命令:
source ~/.zshrc
或者,你可以关闭当前的终端窗口并打开一个新的窗口。
完成这些步骤后,你应该能够在任何地方使用 libpq 提供的命令了,比如 psql。要验证是否成功,你可以运行:
psql --version
这应该会显示 psql 的版本信息。

错误信息表明你尝试连接到 PostgreSQL 服务器时遇到了问题,因为 "dvdrental" 数据库不存在。这是一个常见的错误,发生在尝试连接到一个尚未创建的数据库时。
要解决这个问题,你需 要先创建名为 "dvdrental" 的数据库。你可以使用以下步骤:
-
确保你已经安装了 PostgreSQL 并且服务正在运行。
-
使用
psql命令行工具或其他 PostgreSQL 工具(如 pgAdmin)连接到 PostgreSQL 服务器。 -
连接到一个已经存在的数据库,比如默认的 "postgres" 数据库,因为你需要连接到数据库服务器才能创建新的数据库。在
psql中,你可以使用以下命令连接到 "postgres" 数据库:psql -U username -d postgres这里的
username是你的 PostgreSQL 用户名。 -
一旦连接到数据库服务器,你可以运行以下 SQL 命令来创建 "dvdrental" 数据库:
CREATE DATABASE dvdrental; -
如果你有 "dvdrental" 数据库的备份文件,并且想要恢复它,可以使用
pg_restore工具:pg_restore -U username -d dvdrental /path/to/dvdrental.backup确保替换
username为你的 PostgreSQL 用户名,以及/path/to/dvdrental.backup为备份文件的实际路径。
如果你不是数据库的管理员,你可能需要联系管理员来创建数据库或者给你相应的权限。如果你是管理员,但仍然遇到问题,可能需要检查 PostgreSQL 配置文件(如 postgresql.conf 和 pg_hba.conf)以确保正确设置了连接参数和权限。
链接
PostgreSQL FETCH 与 Limit
在 PostgreSQL 中,FETCH和LIMIT都用于限制查询结果集中的记录数,但它们的上下文和语法略有不同。
LIMIT子句是 SQL 标准的一部分,用于指定要从查询结果中返回的最大记录数。LIMIT通常 与OFFSET子句结合使用,后者指定要跳过的记录数。这种组合常用于实现分页功能。
下面是使用LIMIT的示例:
SELECT * FROM my_table LIMIT 10;
这将返回my_table中的前 10 条记录。
如果你还想跳过前面的一些记录,可以添加OFFSET:
SELECT * FROM my_table LIMIT 10 OFFSET 20;
这将跳过前 20 条记录,并返回之后的 10 条记录。
另一方面,FETCH子句是 SQL:2008 标准的一部分,通常与ORDER BY和OFFSET一起使用,作为CURSOR操作的一部分或在WINDOW函数中使用。FETCH在ORDER BY后面使用时,可以指定返回结果集的一个子集,这与LIMIT的功能相似。
下面是使用FETCH的示例:
SELECT * FROM my_table ORDER BY column_name OFFSET 20 ROWS FETCH FIRST 10 ROWS ONLY;
这个查询会跳过前 20 条记录,并返回之后的 10 条记录。这里的FETCH FIRST 10 ROWS ONLY与LIMIT 10类似,但它是在有ORDER BY和OFFSET子句存在的情况下使用的。
在实际使用中,LIMIT和OFFSET更加普遍,因为它们简洁且易于理解。然而,如果你正在使用 SQL 标准的较新版本,并且需要与标准保持一致,或者在使用CURSOR和WINDOW函数时,可能会使用FETCH。在功能上,它们在限制返回的记录数方面是等效的。
cast

连表查询

自然连接 vs 内连接
自然连接(NATURAL JOIN)确实是一种特殊类型的内连接(INNER JOIN),但它并不仅仅是内连接的简写。自然连接在行为上有一些特定的规则和特性,使其与标准的内连接有所区别。
自然连接的特点是它会自动连接两个表中具有相同名称的所有列。它 不需要显式指定连接条件。自然连接只包括两个表共有的列,并且这些共有列的值必须相等。在结果集中,这些共有列只会出现一次,避免了重复。
这里有一个简单的例子来展示自然连接和内连接的区别:
假设有两个表,employees 和 departments:
employees 表:
+------------+-----------+------------+
| employee_id| name | department |
+------------+-----------+------------+
| 1 | Alice | Sales |
| 2 | Bob | Marketing |
+------------+-----------+------------+
departments 表:
+------------+------------+
| department | location |
+------------+------------+
| Sales | New York |
| Engineering| San Jose |
+------------+------------+
使用内连接(INNER JOIN)时,你需要显式指定连接条件:
SELECT *
FROM employees
INNER JOIN departments
ON employees.department = departments.department;
这将返回:
+------------+------+------------+------------+----------+
| employee_id| name | department | department | location |
+------------+------+------------+------------+----------+
| 1 | Alice| Sales | Sales | New York |
+------------+------+------------+------------+----------+
注意结果中的department列出现了两次。
而使用自然连接(NATURAL JOIN)时,你不需要指定连接条件,数据库系统会自动连接两个表中名称相同的列:
SELECT *
FROM employees
NATURAL JOIN departments;
这将返回:
+------------+------+------------+----------+
| employee_id| name | department | location |
+------------+------+------------+----------+
| 1 | Alice| Sales | New York |
+------------+------+------------+----------+
在这个例子中,department列只出现一次,因为自然连接自动处理了列名匹配并合并了重复的列。
自然连接可以简化查询,但它也可能导致一些不明确或不可预见的行为,特别是当两个表中有多个名称相同的列但实际上不是用于连接的列时。因此,在使用自然连接时需要谨慎,确保你完全理解它的行为以及它如何适用于你的数据模型。
HAVING vs WHERE
在 SQL 中,WHERE和HAVING子句都用于过滤返回的数据,但它们在查询中的作用和使用时机有所不同。以下是WHERE和HAVING子句的主要区别:
WHERE 子句
WHERE子句用于过滤行数据,即在聚合操作之前对数据进行筛选。- 它作用于单个行,根据指定的条件筛选出满足条件的行。
WHERE子句不能与聚合函数一起使用,因为它在数据被聚合前进行过滤。WHERE子句在分组(GROUP BY)之前应用。
例如:
SELECT *
FROM employees
WHERE department = 'Sales';
这个查询返回employees表中属于销售部门的所有员工。
HAVING 子句
HAVING子句用于过滤聚合后的数据,即在聚合操作之后对数据进行筛选。- 它作用于分组后的数据集,根据指定的条件筛选出满足条件的分组。
HAVING子句通常与聚合函数(如SUM(),AVG(),COUNT()等)一起使用。HAVING子句在分组(GROUP BY)之后应用。
例如:
SELECT department, COUNT(*)
FROM employees
GROUP BY department
HAVING COUNT(*) > 5;
这个查询返回拥有超过 5 名员工的部门及其员工数量。
总结
- 使用
WHERE子句在分组前过滤行。 - 使用
HAVING