当前位置:   article > 正文

[SQL系列] 从头开始学PostgreSQL Union Null 别名 触发器_plpgsql union all

plpgsql union all

初级的操作就是CRUD,但是高级的操作也是CRUD,只是语句写的更加复杂,不再是select * from table;这样简单,这次咱们学一些稍微高级点的。下面是上一篇文章。

[SQL系列] 从头开始学PostgreSQL 约束连接_Edward.W的博客-CSDN博客https://blog.csdn.net/u013379032/article/details/131796564

Union 和 Union all

        在 PostgreSQL 中,union 是一种集合运算符,用于将两个或多个 SELECT 语句的结果合并成一个结果集。union 可以接受两个或多个 SELECT 语句作为参数,并将它们返回的结果合并成一个单独的结果集。

        具体来说,union 运算符将两个 SELECT 语句的结果集合并,去除重复的行。合并的结果集将包含所有在至少一个 SELECT 语句中出现的行,但不包含在两个 SELECT 语句中都未出现的行。

  1. testdb=# select * from students;
  2. id | name | age | gender | class_id
  3. ----+--------+-----+--------+----------
  4. 1 | 张三 | 18 || 1
  5. 2 | 李四 | 19 || 1
  6. 3 | 王五 | 20 || 2
  7. 4 | 赵六 | 18 || 2
  8. 5 | 陈七 | 19 || 3
  9. 6 | 孙八 | 20 || 3
  10. 7 | 周九 | 18 || 4
  11. 8 | 吴十 | 19 || 4
  12. 9 | 郑十一 | 20 || 5
  13. 10 | 王十二 | 18 || 5
  14. (10 rows)
  15. testdb=# select * from students where age < 20
  16. union
  17. select * from students where class_id < 4;
  18. id | name | age | gender | class_id
  19. ----+--------+-----+--------+----------
  20. 5 | 陈七 | 19 || 3
  21. 10 | 王十二 | 18 || 5
  22. 2 | 李四 | 19 || 1
  23. 1 | 张三 | 18 || 1
  24. 4 | 赵六 | 18 || 2
  25. 6 | 孙八 | 20 || 3
  26. 7 | 周九 | 18 || 4
  27. 3 | 王五 | 20 || 2
  28. 8 | 吴十 | 19 || 4
  29. (9 rows)

第一个表获取到了年龄20下的学生,第二个表获取了前3个班的学生,然后通过union合并后,可以看到,结果的表既有20岁的学生,也有4班的学生,也就是将前两张表合并起来,但是去除了重复的行。

这边另外介绍一下Union all

  1. testdb=# select * from students where age < 20
  2. union all
  3. select * from students where class_id < 4;
  4. id | name | age | gender | class_id
  5. ----+--------+-----+--------+----------
  6. 1 | 张三 | 18 || 1
  7. 2 | 李四 | 19 || 1
  8. 4 | 赵六 | 18 || 2
  9. 5 | 陈七 | 19 || 3
  10. 7 | 周九 | 18 || 4
  11. 8 | 吴十 | 19 || 4
  12. 10 | 王十二 | 18 || 5
  13. 1 | 张三 | 18 || 1
  14. 2 | 李四 | 19 || 1
  15. 3 | 王五 | 20 || 2
  16. 4 | 赵六 | 18 || 2
  17. 5 | 陈七 | 19 || 3
  18. 6 | 孙八 | 20 || 3
  19. (13 rows)

        Union 会自动去除多个结果集合中的重复行,只返回一个结果集。而 Union All 则会将所有结果集合中的行都返回,不管它们是否重复。因此,如果需要返回所有行,而不管它们是否重复,则

可以使用 Union All。
        另外,Union 在合并结果时还会默认进行排序,而 Union All 则不会。如果需要对结果进行排序,可以使用 Order By 子句进行指定。
        在使用 Union 或 Union All 时,需要确保两个结果集的列数和数据类型相等,否则可能会出现错误。而在使用 Union All 时,还可以使用类似 Select 语句中的通配符(如 * )来指定要合并的列。

NULL

        NULL代表空值,插入数据的时候有些没插入的数据自然就是NULL,我们可以用IS NULL和NOT NULL来进行筛选。

我们建个表来看看:

  1. testdb=# CREATE TABLE engineer (
  2. id INT PRIMARY KEY,
  3. name VARCHAR(50),
  4. age INT,
  5. gender CHAR(1),
  6. address VARCHAR(200),
  7. created_at TIMESTAMP
  8. );
  9. CREATE TABLE
  10. testdb=# INSERT INTO engineer (id, name, age, gender, address, created_at) VALUES
  11. (1, 'John', 30, 'M', 'New York', '2023-02-18 10:00:00'),
  12. (2, 'Mary', 25, 'F', 'Los Angeles', '2023-02-18 10:00:00'),
  13. (3, 'Peter', 35, 'M', 'Chicago', '2023-02-18 10:00:00'),
  14. (4, 'Jane', 28, 'F', 'San Francisco', '2023-02-18 10:00:00'),
  15. (5, 'Bob', 40, 'M', 'Boston', '2023-02-18 10:00:00'),
  16. (6, ' NULL', 22, 'F', 'Washington DC', '2023-02-18 10:00:00'),
  17. (7, ' NULL', 38, 'M', 'Atlanta', '2023-02-18 10:00:00'),
  18. (8, ' NULL', 25, 'F', 'Miami', '2023-02-18 10:00:00'),
  19. (9, ' NULL', 32, 'M', 'Philadelphia', '2023-02-18 10:00:00'),
  20. (10, ' NULL', 28, 'F', 'Dallas', '2023-02-18 10:00:00');
  21. INSERT 0 10
  22. testdb=# select * from engineer;
  23. id | name | age | gender | address | created_at
  24. ----+-------+-----+--------+---------------+---------------------
  25. 1 | John | 30 | M | New York | 2023-02-18 10:00:00
  26. 2 | Mary | 25 | F | Los Angeles | 2023-02-18 10:00:00
  27. 3 | Peter | 35 | M | Chicago | 2023-02-18 10:00:00
  28. 4 | Jane | 28 | F | San Francisco | 2023-02-18 10:00:00
  29. 5 | Bob | 40 | M | Boston | 2023-02-18 10:00:00
  30. 6 | NULL | 22 | F | Washington DC | 2023-02-18 10:00:00
  31. 7 | NULL | 38 | M | Atlanta | 2023-02-18 10:00:00
  32. 8 | NULL | 25 | F | Miami | 2023-02-18 10:00:00
  33. 9 | NULL | 32 | M | Philadelphia | 2023-02-18 10:00:00
  34. 10 | NULL | 28 | F | Dallas | 2023-02-18 10:00:00
  35. (10 rows)

这边的NULL不是真的NULL值,只是名字叫做'NULL',我们修改下:

  1. testdb=# update engineer set name = null, age = null where name = ' NULL';
  2. UPDATE 5
  3. testdb=# select * from engineer;
  4. id | name | age | gender | address | created_at
  5. ----+-------+-----+--------+---------------+---------------------
  6. 1 | John | 30 | M | New York | 2023-02-18 10:00:00
  7. 2 | Mary | 25 | F | Los Angeles | 2023-02-18 10:00:00
  8. 3 | Peter | 35 | M | Chicago | 2023-02-18 10:00:00
  9. 4 | Jane | 28 | F | San Francisco | 2023-02-18 10:00:00
  10. 5 | Bob | 40 | M | Boston | 2023-02-18 10:00:00
  11. 6 | | | F | Washington DC | 2023-02-18 10:00:00
  12. 7 | | | M | Atlanta | 2023-02-18 10:00:00
  13. 8 | | | F | Miami | 2023-02-18 10:00:00
  14. 9 | | | M | Philadelphia | 2023-02-18 10:00:00
  15. 10 | | | F | Dallas | 2023-02-18 10:00:00
  16. (10 rows)
  17. testdb=# select * from engineer where name is null;
  18. id | name | age | gender | address | created_at
  19. ----+------+-----+--------+---------------+---------------------
  20. 6 | | | F | Washington DC | 2023-02-18 10:00:00
  21. 7 | | | M | Atlanta | 2023-02-18 10:00:00
  22. 8 | | | F | Miami | 2023-02-18 10:00:00
  23. 9 | | | M | Philadelphia | 2023-02-18 10:00:00
  24. 10 | | | F | Dallas | 2023-02-18 10:00:00
  25. (5 rows)
  26. testdb=# select * from engineer where age is not null;
  27. id | name | age | gender | address | created_at
  28. ----+-------+-----+--------+---------------+---------------------
  29. 1 | John | 30 | M | New York | 2023-02-18 10:00:00
  30. 2 | Mary | 25 | F | Los Angeles | 2023-02-18 10:00:00
  31. 3 | Peter | 35 | M | Chicago | 2023-02-18 10:00:00
  32. 4 | Jane | 28 | F | San Francisco | 2023-02-18 10:00:00
  33. 5 | Bob | 40 | M | Boston | 2023-02-18 10:00:00
  34. (5 rows)

别名

这个很好说明,就是比如有些表的名字很长,所以我们就直接给个简称,依据上面的表我们给个例子。

  1. testdb=# select * from engineer as e where age is null;
  2. id | name | age | gender | address | created_at
  3. ----+------+-----+--------+---------------+---------------------
  4. 6 | | | F | Washington DC | 2023-02-18 10:00:00
  5. 7 | | | M | Atlanta | 2023-02-18 10:00:00
  6. 8 | | | F | Miami | 2023-02-18 10:00:00
  7. 9 | | | M | Philadelphia | 2023-02-18 10:00:00
  8. 10 | | | F | Dallas | 2023-02-18 10:00:00
  9. (5 rows)
  10. testdb=# select c.id as cid, c.name as cname, e.name as ename from company as c, engineer as e where c.id = e.id;
  11. cid | cname | ename
  12. -----+-------+-------
  13. 2 | CC | Mary
  14. 4 | Eoe | Jane
  15. 3 | Dod | Peter
  16. 5 | Fof | Bob
  17. 6 | Gog |
  18. (5 rows)

触发器

        SQL 触发器是一种特殊的存储过程,它与普通的存储过程不同,它的执行是由事件来触发的,而不是由程序调用或手工启动的。当对 SQL 表进行操作(如 insert、delete、update 等)时,触发器会自动执行。触发器可以用于加强数据的完整性约束和业务规则等。
        触发器可以分为两种类型:语句级触发器和行级触发器。语句级触发器在触发事件时执行一次,无论是否有行发生变化,而行级触发器只会在发生变化的行上执行。触发器可以设置触发时间,包括 before(在事件发生之前)和 after(在事件发生之后)两种。

触发器一般和函数一起使用。我们直接看个例子

  1. #创建一个函数
  2. CREATE OR REPLACE FUNCTION update_all_students_view()
  3. RETURNS TRIGGER
  4. AS $$
  5. BEGIN
  6. IF NEW.age > 0 THEN
  7. INSERT INTO all_students (name, age)
  8. VALUES (NEW.name, NEW.age);
  9. END IF;
  10. RETURN NEW;
  11. END;
  12. $$ LANGUAGE plpgsql;
  13. #创建一个触发器
  14. CREATE TRIGGER update_all_students
  15. AFTER INSERT
  16. ON students
  17. FOR EACH ROW
  18. WHEN (NEW.age > 0)
  19. EXECUTE FUNCTION update_all_students_view();
  20. #触发它
  21. testdb=# INSERT INTO students (name, age) VALUES ('张三', 18);
  22. INSERT INTO students (name, age) VALUES ('李四', 0);
  23. #这时候第二行就无法插入成功,因为年龄必须大于0
  24. #删除trigger
  25. drop trigger update_all_students on students;

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/441378
推荐阅读
相关标签
  

闽ICP备14008679号