📅  最后修改于: 2020-11-30 01:31:07             🧑  作者: Mango
在本节中,我们将了解PostgreSQL Subquery的工作原理,这使我们能够创建困难的查询。我们还看到带有不同子句(例如SELECT,FROM和WHERE) ,不同条件(例如IN,EXISTS )和不同查询(例如SELECT,INSERT,UPDATE和DELETE)的子查询的示例。
子查询是在另一个查询中使用的命令。相反, INNER SELECT或INNER语句称为SUBQUERY ,而OUTER SELECT或OUTER语句称为MAIN命令。 PostgreSQL子查询包含在括号中。
PostgreSQL子查询可以与不同的子句一起使用,例如SELECT,FROM, WHERE和HAVING子句。
我们还可以将PostgreSQL子查询与SELECT , INSERT , UPDATE和DELETE命令以及不同的运算符(如<,>,=,<=,> =, BETWEEN和IN等)组合在一起。
注意:在PostgreSQL中,子查询不允许与ORDER BY子句一起使用。但是我们可以使用GROUP BY命令代替ORDER BY命令执行类似的功能。
让我们看不同的示例,以了解PostgreSQL子查询如何与各种子句一起工作。
PostgreSQL子查询也可以与SELECT子句结合使用。
当我们希望借助诸如平均值,计数,总和,最大值和最小值函数之类的聚合函数来获取计算时,将使用子查询,但是我们不希望聚合函数用于MAIN查询中。
在这里,我们将显示如何在SELECT子句中使用子查询。
我们从javatpoint数据库中获取car表,以从表中选择特定数据。
SELECT c1.car_name, c1.car_model,
(SELECT MIN (car_id)
FROM car c2
WHERE c1.car_id = c2.car_id) Subquery1
FROM car c1;
输出量
执行上述命令后,我们将获得以下输出:
在上面的示例中,我们在SELECT子句中创建了一个子查询,如下所示:
并且我们将子查询的别名命名为Subquery1 ,这将是用来引用上述子查询或任何这些字段的名称。
注:像平均,计数,总和,最大值,最小值和函数集合函数在子查询中是经常使用的。并且子查询必须返回单个值,这就是为什么我们将子查询放在SELECT子句中的原因。
PostgreSQL子查询也可以与FROM子句结合使用。
为此,我们从javatpoint数据库中获取Course和Course_categories表,该表是我们在PostgreSQL教程的前面部分中创建的。
SELECT course.course_name, Subquery2.course_category_id
FROM course,
(SELECT course_categories.course_category_id, course_categories.course_category,
COUNT (course_category_id) AS total
FROM course_categories
GROUP BY course_categories.course_category_id, course_categories.course_category) Subquery2
WHERE Subquery2.course_category_id = course.course_id;
输出量
成功执行以上命令后,我们将获得以下输出:
在上面的示例中,我们在FROM子句中创建了一个子查询,如下所示:
并且我们将子查询的别名命名为Subquery2 ,这将是用来引用上述子查询或任何这些字段的名称。
PostgreSQL子查询最常与WHERE子句一起使用。这些子查询也称为嵌套子查询。
为此,我们从Javatpoint数据库中获取Client和Client_details表,该表是我们在PostgreSQL教程的前面部分中创建的。
SELECT c.client_id, c.client_name, c.client_profession
FROM client c
WHERE c.client_id IN
(SELECT cd.client_id
FROM client_details cd
WHERE cd.client_id < 6
AND c.client_name LIKE 'M%');
输出量
在执行上述命令后,我们将获得以下结果:
在上面的示例中,我们在WHERE子句中创建了一个子查询,如下所示:
上面的子查询语句将使我们能够从client_details表中识别出client_id小于6的所有client_id值,并且client_name以'M'开头。子查询用于在IN条件的帮助下过滤MAIN查询的输出。
在下面的命令中,我们使用了INNER Join条件作为以下子查询的替代方法:
SELECT c.client_id, c.client_name, c.client_profession
FROM client c
INNER JOIN Client_details cd
ON c.client_id= cd.client_id
WHERE cd.client_id < 6
AND c.client_name LIKE 'M%';
输出量
执行上述命令后,与上述带有WHERE子句的子查询命令相比,我们将得到类似的结果:
注意:与原始子查询相比,INNER JOIN条件的执行效率更高,很重要的一点是,并不是所有的子查询都可以在PostgreSQL联接的帮助下进行重写。
让我们看不同的示例,以了解PostgreSQL子查询如何在不同条件下工作。
PostgreSQL子查询也可以与EXISTS子句结合使用。
以下语法用于显示具有EXISTS条件的子查询的工作:
EXISTS subquery
EXISTS条件仅保留从子查询返回的行数,而不保留行的内容。因此,我们可以使用以下EXISTS条件的语法:
EXISTS
(SELECT 1
FROM table_name
WHERE condition);
让我们看一个示例示例,以更好地理解带有EXISTS条件的子查询。
为此,我们从javatpoint数据库中获取employee和department表,该数据库是在PostgreSQL教程的前面部分中创建的。
SELECT emp_fname, emp_lname
FROM employee
WHERE EXISTS (
SELECT 1
FROM department
WHERE department.emp_id = employee.emp_id
);
输出量
执行上述命令后,我们将获得以下输出:
正如我们在上面的屏幕截图中看到的那样,这些命令的工作方式类似于emp_id列上的PostgreSQL Inner Join。
尽管在部门表中有一些匹配的行,但是它在雇员表中至少返回了一行。
PostgreSQL子查询也可以与IN Condition结合使用。
在这里,我们使用带有IN Condition和WHERE子句的子查询。
在下面的示例中,我们采用与上面的示例相似的表(employee和department)。
在这里,我们将尝试获取在2010-08-22和2010-08-26之间具有加入日期的员工信息:
SELECT department.emp_id
FROM employee
INNER JOIN department
ON department.emp_id = employee.emp_id
WHERE joining_date
BETWEEN '2010-08-22' AND '2010-08-26';
输出量
执行上述命令后,我们将得到以下结果:
上面的命令将返回各行。因此,我们可以在以下语句的WHERE子句中将此命令用作子查询:
SELECT job_id, job_description
FROM jobs
WHERE job_id IN (
SELECT department.emp_id
FROM employee
INNER JOIN department
ON department.emp_id = employee.emp_id
WHERE joining_date
BETWEEN '2010-08-22' AND '2010-08-26'
);
输出量
成功执行以上命令后,我们将获得以下输出:
让我们看不同的示例,以了解PostgreSQL子查询如何与多个语句一起使用。
我们将使用带有SELECT命令的子查询进行显示。
为此,我们从Javatpoint数据库中获取Car表,以从表中检索所有记录。
让我们假设我们需要确定那些car_price高于平均car_pirce的汽车。因此,为此,我们将执行以下两个步骤:
步骤1
首先,我们将使用SELECT命令和(AVG)平均值函数确定平均车价。
以下语句用于从car表中获取平均car_price:
SELECT
AVG (car_price)
FROM car;
输出量
成功执行以上命令后,我们将获得以下输出:
正如我们在下面的屏幕截图中看到的,平均car_price为103109.500 。
第2步
之后,我们将在第二个SELECT命令中获取第一个命令的输出,以从car表中识别汽车。
在下面的命令中,我们将获得car_id,即car_name,其car_price大于平均car_price :
SELECT car_id, car_name, car_price
FROM car
WHERE car_price >103109.5;
输出量
在执行上述命令后,我们将获得以下结果:
我们可以看到,上面的代码设计得不好,因为它需要两个步骤来实现查询。因此,我们需要在单个命令中允许第一条命令的输出到第二条命令。
在这种情况下,我们将使用PostgreSQL子查询的概念,因为子查询是一个命令,该命令嵌套在其他命令中,例如INSERT,SELECT,UPDATE和DELETE。
在PostgreSQL教程的这一部分中,我们将一一理解所有的语句。
带有SELECT命令的PostgreSQL子查询的语法如下:
SELECT column_name
FROM table_name
WHERE column_name expression operator(
SELECT column_name
FROM able_name
WHERE condition);
为了创建子查询,我们将第二个命令与WHERE子句一起放在括号中作为表达式:
SELECT car_id, car_name, car_price
FROM car
WHERE car_price >(
SELECT
AVG (car_price)
FROM
car );
输出量
执行上述命令后,我们将获得以下输出:
正如我们可以看到的那样,在执行完这两个命令之后,我们将获得类似的输出,但是Subquery命令更加有效和可读。
注意:PostgreSQL按照以下顺序执行包含子查询的命令:
我们将显示如何在INSERT语句中使用子查询。在INSERT命令中,子查询返回的记录用于插入另一个表。
在PostgreSQL子查询中,可以使用任何日期函数和字符更改所选数据。
带有INSERT命令的PostgreSQL子查询的语法如下:
INSERT INTO table_name (column1, column2,.. columnN)
SELECT column_names
FROM table_name
WHERE VALUE OPERATOR
为此,我们要从组织数据库中获取雇员和部门表,并使用AND运算符将记录从一个表插入到另一个表。
在下面的示例中,我们将记录从部门表插入到雇员表中。
我们从部门表中获取电话和地址列记录,dept_id小于5,部门名称为OPERATION 。
INSERT INTO employee
(phone, address)
SELECT phone, address
FROM department
WHERE dept_id < 5
AND department_name = 'OPERATION';
输出量
执行完上述命令后,我们将获得以下消息窗口,显示该值已成功插入到employee表中。
要检查记录是否已插入到employee表中,我们将使用SELECT命令,如下所示:
SELECT * FROM employee;
输出量
执行上述命令后,我们将获得以下输出:
正如我们在上面的屏幕截图中看到的那样, PostgreSQL子查询将一条记录插入到employee表中。
我们将显示如何在UPDATE语句中使用子查询。如果我们将子查询与UPDATE命令一起使用,则可以更新表中的一列或多列。
带有UPDATE命令的PostgreSQL子查询的语法如下:
UPDATE table
SET column_name = new_value
WHERE VALUE OPERATOR (
SELECT column_name
FROM table_name
WHERE condition
);
为此,我们从Javatpoint数据库中获取Summer_fruits和Winter_fruits表,该表是我们在PostgreSQL教程的前面部分中创建的。
在下面的命令,PostgreSQL的子查询被用于从在winter_fruits表中的列winter_fruits_name其中winter_fruits' wf_id列等于summer_fruits' sf_id柱更新所述summer_fruits表Fruits_name列值。
UPDATE summer_fruits
SET Fruits_name=(SELECT winter_fruits.winter_fruits_name
FROM winter_fruits
WHERE winter_fruits.wf_id = summer_fruits.sf_id);
输出量
执行完上面的命令后,我们将获得以下输出,可以看到summer_fruits表已成功更新。
现在,我们将使用Select命令来检查summer_fruits表中的特定记录是否已更新:
SELECT * FROM summer_fruits;
输出量
执行上述命令后,我们将得到以下结果:
正如我们在上面的屏幕快照中看到的那样, PostgreSQL子查询将6条记录更新到了summer_fruits表中。
与上面提到的任何其他语句一样,我们将显示如何将子查询与DELETE语句一起使用。
带有DELETE命令的PostgreSQL子查询的语法如下:
DELETE
FROM table_name
WHERE value operator (
SELECT column_name
FROM table_name
WHERE condition
);
在下面的示例中,我们从Javatpoint数据库中获取Course和Course_categories表,还使用EXISTS运算符从表中删除特定记录。
在下面的命令,PostgreSQL的子查询被用来从课程表,其中从场表COURSE_ID,并从Course_categories表course_category_id相等删除所有记录。
DELETE FROM Course
WHERE EXISTS (
SELECT course_name
FROM Course_categories
WHERE Course.course_id = Course_categories.course_category_id
);
输出量
执行完上述命令后,我们将获得以下消息窗口,显示记录已成功从“课程”表中删除。
现在,我们将使用“选择”命令来检查“课程”表中的特定记录是否已删除:
SELECT *
FROM Course;
输出量
成功执行以上命令后,我们将获得以下输出:
PostgreSQL子查询的使用有助于我们创建复杂的命令。在PostgreSQL子查询部分中,我们学习了以下主题: