📜  PostgreSQL子查询

📅  最后修改于: 2020-11-30 01:31:07             🧑  作者: Mango

PostgreSQL子查询

在本节中,我们将了解PostgreSQL Subquery的工作原理,这使我们能够创建困难的查询。我们还看到带有不同子句(例如SELECT,FROM和WHERE) ,不同条件(例如IN,EXISTS )和不同查询(例如SELECT,INSERT,UPDATE和DELETE)子查询的示例。

PostgreSQL子查询简介

子查询是在另一个查询中使用的命令。相反, INNER SELECTINNER语句称为SUBQUERY ,而OUTER SELECTOUTER语句称为MAIN命令。 PostgreSQL子查询包含在括号中

PostgreSQL子查询可以与不同的子句一起使用,例如SELECT,FROM, WHEREHAVING子句

我们还可以将PostgreSQL子查询与SELECTINSERTUPDATEDELETE命令以及不同的运算符(如<,>,=,<=,> =, BETWEENIN等)组合在一起。

注意:在PostgreSQL中,子查询不允许与ORDER BY子句一起使用。但是我们可以使用GROUP BY命令代替ORDER BY命令执行类似的功能。

具有不同子句的PostgreSQL子查询的示例

让我们看不同的示例,以了解PostgreSQL子查询如何与各种子句一起工作。

带有SELECT子句的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子句中的原因。

带有FROM子句的PostgreSQL子查询示例

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 ,这将是用来引用上述子查询或任何这些字段的名称。

带有WHERE子句的PostgreSQL子查询示例

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条件的PostgreSQL子查询示例

PostgreSQL子查询也可以与EXISTS子句结合使用。

以下语法用于显示具有EXISTS条件的子查询的工作:

EXISTS subquery

EXISTS条件仅保留从子查询返回的行数,而不保留行的内容。因此,我们可以使用以下EXISTS条件的语法:

EXISTS 
(SELECT 1 
FROM table_name 
WHERE condition);
  • 子查询可以是EXISTS条件的输入。如果子查询返回任何行,则EXISTS条件将返回TRUE
  • 如果子查询不返回任何行,则EXISTS条件的输出将返回FALSE

让我们看一个示例示例,以更好地理解带有EXISTS条件的子查询

为此,我们从javatpoint数据库中获取employeedepartment表,该数据库是在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。

尽管在部门表中有一些匹配的行,但是它在雇员表中至少返回了一行。

具有IN条件的PostgreSQL子查询示例

PostgreSQL子查询也可以与IN Condition结合使用。

在这里,我们使用带有IN Condition和WHERE子句的子查询。

在下面的示例中,我们采用与上面的示例相似的表(employee和department)。

在这里,我们将尝试获取在2010-08-222010-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子查询示例

让我们看不同的示例,以了解PostgreSQL子查询如何与多个语句一起使用。

带有SELECT语句的PostgreSQL子查询示例

我们将使用带有SELECT命令的子查询进行显示。

为此,我们从Javatpoint数据库中获取Car表,以从表中检索所有记录。

让我们假设我们需要确定那些car_price高于平均car_pirce的汽车。因此,为此,我们将执行以下两个步骤:

步骤1

首先,我们将使用SELECT命令和(AVG)平均值函数确定平均车价

以下语句用于从car表中获取平均car_price:

SELECT
AVG (car_price)
FROM car;

输出量

成功执行以上命令后,我们将获得以下输出:

正如我们在下面的屏幕截图中看到的,平均car_price103109.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命令的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按照以下顺序执行包含子查询的命令:

  • 首先,它将实现子查询。
  • 然后,它将获取输出并将其传递给OUTER SELECTOUTER QUERY
  • 最后,它将执行OUTER SELECT

带有INSERT语句的PostgreSQL子查询示例

我们将显示如何在INSERT语句中使用子查询。在INSERT命令中,子查询返回的记录用于插入另一个表。

在PostgreSQL子查询中,可以使用任何日期函数和字符更改所选数据。

带有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语句的PostgreSQL子查询示例

我们将显示如何在UPDATE语句中使用子查询。如果我们将子查询与UPDATE命令一起使用,则可以更新表中的一列或多列。

带有UPDATE语句的PostgreSQL子查询的语法

带有UPDATE命令的PostgreSQL子查询的语法如下:

UPDATE table  
SET column_name = new_value  
WHERE VALUE OPERATOR (
           SELECT column_name 
           FROM table_name 
           WHERE condition
);  

为此,我们从Javatpoint数据库中获取Summer_fruitsWinter_fruits表,该表是我们在PostgreSQL教程的前面部分中创建的。

在下面的命令,PostgreSQL子查询被用于从在winter_fruits表中的列winter_fruits_name其中winter_fruits' wf_id列等于summer_fruits' sf_id柱更新所述summer_fruitsFruits_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语句的PostgreSQL子查询示例

与上面提到的任何其他语句一样,我们将显示如何将子查询与DELETE语句一起使用。

带有DELETE语句的PostgreSQL子查询的语法

带有DELETE命令的PostgreSQL子查询的语法如下:

DELETE 
FROM table_name  
WHERE value operator (
SELECT column_name  
      FROM table_name 
       WHERE condition
);   

在下面的示例中,我们从Javatpoint数据库中获取CourseCourse_categories表,还使用EXISTS运算符从表中删除特定记录。

在下面的命令,PostgreSQL子查询被用来从课程表,其中从COURSE_ID,并从Course_categoriescourse_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子查询部分中,我们学习了以下主题:

  • 我们使用带有SELECT子句的子查询来选择特定的表记录。
  • 我们使用带有FROM子句的子查询来获取表列表。
  • 我们使用带有WHERE子句的子查询来过滤输出并应用条件。
  • 一旦子查询返回至少一行,我们就使用带有EXISTS条件的子查询来检查条件是否得到满足。
  • 如果表达式匹配值列表中的任何值,则可以使用带有IN条件测试的子查询。
  • 我们将子查询与SELECT命令一起使用以获取特定的表记录。
  • 我们使用带INSERT的子查询命令将记录从一个表插入到另一个表。
  • 我们将子查询与UPDATE语句一起使用来更新表的记录。
  • 我们将子查询与DELETE语句一起使用,以删除特定表的记录。