SQL全方位攻略:3.SQL标准

系列文章目录

1.数据库介绍
2.SQL介绍


文章目录

  • 系列文章目录
  • 3. SQL标准
    • 3.1 ISO SQL和ANSI SQL
    • 3.2 SQL标准的历史
      • 1. SQL-86
      • 2. SQL-89 (SQL1)
      • 3. SQL-92 (SQL2)
      • 4. SQL:1999 (SQL3)
        • 4.1 公共表达式(CTEs)
        • 4.2 GROUP BY语句扩展
      • 5. SQL:2003
        • 窗口函数
      • 6. SQL:2006
        • 支持XML
      • 7. SQL:2008
        • 7.1. 增强了MERGE和DIAGNOSTIC语句
        • 7.2. 引入了TRUNCATE TABLE语句
        • 7.3. CASE表达式支持逗号分隔的WHEN子句
        • 7.4. 引入了INSTEAD OF触发器
        • 7.5. 支持JOIN分区表
        • 7.6. 引入了FETCH子句
        • 7.7. 允许在游标定义之外使用ORDER BY
        • 7.8. 支持各种XQuery正则表达式/模式匹配
        • 9. 派生字段名增强
      • 8. SQL:2011
        • 8.1. DELETE IN MERGE(在合并语句中使用删除)
        • 8.2. Pipeline DML(管道DML)
        • 8.3. Limited Fetch Capability(有限的提取能力)
        • 8.4. 窗口函数增强
          • 8.4.1. LAG和LEAD函数
          • 8.4.2. Navigation within a window
      • 9. SQL:2016
        • 9.1. JSON支持
        • 9.2. 表值函数(Table-Valued Functions)
      • 10. SQL:2019
        • 多维数组(SQL/MDA)
    • 总结
    • 参考

【免责声明】文章仅供学习交流,观点代表个人,与任何公司无关。
编辑|SQL和数据库技术(ID:SQLplusDB)


3. SQL标准

为了确保不同厂商数据库系统之间的兼容性和互操作性,用于控制SQL查询的行为和数据存储结构等方面的统一性,由国际组织或者国家标准化组织制定和发布了一系列的标准规范。

3.1 ISO SQL和ANSI SQL

ISO SQL和ANSI SQL都是国际上公认的SQL标准,该标准定义了SQL语言的语法、规则以及对数据库访问的方法。

  • ISO SQL:全称是“International Organization for Standardization Structured
    Query Language”,由国际标准化组织(ISO)/国际电工委员会(IEC)制定的国际SQL标准。它广泛应用于欧洲和亚洲等地区的数据库管理系统中。ISO SQL是一个更严格的标准,它强制规定了数据库管理系统必须具备哪些特征和能力,使得数据库知识可以更加通用。

  • ANSI SQL:全称是 “American National Standard Institute Structured Query
    Language”, 由美国国家标准协会制定的美国SQL标准。它主要用于在美国和加拿大地区的数据库管理系统中。

ISO SQL是全球范围内的SQL规范,目的是确保SQL语言的一致性和交互性。ANSI是ISO和International Electrotechnical Commission(IEC)的成员之一,ANSI 会发布与国际标准组织相应的美国标准。因此,ANSI SQL和ISO SQL并不是完全等同的,但从某种角度而言,可以说ANSI SQL是ISO SQL的一个子集。
虽然ANSI SQL和ISO SQL之间可能存在一些差异或细微的不同,但通常来说它们的区别并不大。它们之间通常会建立联系和合作,以确保它们的标准可以互相认可和接受,所以不会影响SQL的核心概念和基本规则。

3.2 SQL标准的历史

1. SQL-86

SQL-86的全称是"American National Standard for Information Systems–Database Language–SQL",是由美国国家标准学会(ANSI)于1986年制定了第一个SQL标准“ANSI/INCITS 135-1986”。当时ISO并未参与SQL-86的制定,因此该标准只是一份美国国家标准(ANSI标准),而非ISO标准。几个月之后,ISO发表了一个技术上相同的标准,ISO 9075-1987,将SQL从早期仅限于IBM数据库的狭窄领域带到了国际舞台上。

标准主要规定了SQL语言的基本语法:

- SELECT、INSERT、UPDATE和DELETE语句的语法
- SELECT语法允许使用WHERE进行过滤,使用GROUP BY对多个列(但不是按表达式)进行分组,并使用HAVING对组进行过滤
- SELECT语法允许子查询
- 没有明确的JOIN语法
- 可以创建表(只支持UNIQUE和NOT NULL限制)
- 引入字符字符串和数字(NUMERIC、DECIMAL、INTEGER、SMALLINT、FLOAT、REAL和DOUBLE PRECISION)的数据类型
- 创建视图和授予权限
- 没有ALTER、DROP或REVOKE语句

虽然SQL-86在后来的SQL标准中被逐渐淘汰,但在SQL的发展历史中具有重要的里程碑意义。
下面是一个SQL-86的示例:

创建表seller:

CREATE TABLE seller (
    seller_id INT,
    seller_name VARCHAR(50),
    seller_address VARCHAR(200),
    seller_phone VARCHAR(20)
);

插入数据:

INSERT INTO seller VALUES (1, 'Tom', 'New York', '123456');

选择数据:

SELECT seller_name FROM seller WHERE seller_id = 1;

2. SQL-89 (SQL1)

SQL-89由ISO/IEC(国际标准化组织和国际电工委员会)联合制定的标准,编号为 ISO/IEC 9075:1989,同时美国国家标准学会(ANSI)制定为ANSI标准,编号为 ANSI/INCITS 135-1992,是SQL-86的更新版本,SQL-89 又称为SQL1。

SQL-89最重要的新功能是引入了完整性约束。这意味着可以在创建表时定义列的约束条件,以保证数据的完整性和一致性。

例如,下面是一个创建了一个具有主键和外键约束的表的示例:

CREATE TABLE employees (
  employee_id INTEGER PRIMARY KEY,
  first_name VARCHAR(50),
  last_name VARCHAR(50),
  department_id INTEGER,
  FOREIGN KEY (department_id) REFERENCES departments(department_id)
);

在这个例子中,employees表中的employee_id被定义为主键,这意味着每个记录都必须具有唯一的employee_id值。department_id被定义为外键,它必须与departments表中的department_id列中的值匹配。通过这些约束条件,可以确保employees表中的数据是完整和一致的。

3. SQL-92 (SQL2)

SQL-92 由ISO/IEC(国际标准化组织和国际电工委员会)联合制定的标准,编号为 ISO/IEC 9075-1:1992。同时,SQL-92也被美国国家标准学会(ANSI)采纳为ANSI标准,编号为 ANSI/INCITS 135-1992,SQL-92 又称为SQL2。

SQL-92是SQL的一个重要标准版本,它引入了许多新特性,例如:

- 明确的JOIN语法和引进外连接:LEFT JOIN、RIGHT JOIN、FULL JOIN。
- 引入NATURAL JOIN和CROSS JOIN。
- 引入集合操作(集合并、集合交和集合差)。
- 引入条件表达式CASE WHEN。
- 新增标量操作:字符串串联、字串提取以及日期和时间计算。
- CAST运算符,允许将值显式转换为类型。
- 新的数据定义语句:ALTER和DROP表和视图
- 新的数据类型:日期、时间、时间戳、interval、二进制串、字符串和国家字符串。
- 信息模式(Information schema):获取数据库元数据的标准方法,如表名、表列、列类型和表约。
- 引入了临时表
- 事务隔离级别
- 动态SQL

下面是一个SQL-92的JOIN语法示例:

SELECT *
FROM Employee
JOIN Department
ON Employee.DepartmentID = Department.DepartmentID;

4. SQL:1999 (SQL3)

全称是“ISO/IEC 9075:1999”,也称为SQL3 ,是在ISO和ANSI共通指导下对SQL标准进行的第四次修改。
从这个版本开始,标准名称使用冒号而不是连字符,以保持与其他ISO标准名称的一致性。

SQL:1999它引入了许多新特性和现代SQL的重要功能,例如:

4.1 公共表达式(CTEs)

SQL:1999引入了公共表达式( Common Table Expressions,CTEs),这是一个非常有用的功能,可以让你组织并简化长而复杂的SQL查询,并使其更易读。在使用WITH语法时,CTEs可以在查询中声明并引用,从而消除了重复代码和多余的子查询。

CTE的用法如下:

WITH cte_name (column_list) AS (
   SELECT ...
   FROM ...
   WHERE ...
   ), 
   ...
SELECT ...
FROM table1
JOIN cte_name ON ...
WHERE ...

其中,cte_name是CTE的名称,column_list是列名列表,SELECT语句是常规的查询,与常规查询一样,可以使用聚合函数、JOIN、子查询等功能。然后,通过将查询定义为CTE,可以在查询中使用简化的语法引用查询。

此外,当使用WITH RECURSIVE语法时,CTEs还可以递归处理分层数据。以下是一个示例,演示如何使用CTE来查找递归树中某个节点的所有祖先:

WITH RECURSIVE ancestors AS (
   SELECT id, parent_id
   FROM table1
   WHERE id = 10
   UNION ALL
   SELECT table1.id, table1.parent_id
   FROM table1
   JOIN ancestors ON table1.id = ancestors.parent_id
   )
SELECT *
FROM ancestors;

在这个示例中,CTE的名称是ancestors,定义了两个查询,第一个查询用于查找开始节点,第二个查询用于查找节点的所有祖先,使用JOIN将所有祖先连接在一起。

4.2 GROUP BY语句扩展

SQL:1999标准引入了在线分析处理(OLAP)功能,这包括在准备业务报告时使用的功能。其中,GROUP BY语句进一步扩展了ROLLUP、CUBE和GROUPING SETS等聚合操作,这些聚合操作非常有用。

以下是SQL:1999中使用GROUP BY扩展操作的一个示例。

首先,我们创建一个名为sales_table的表,该表包含了销售数据:

CREATE TABLE sales_table (
    region VARCHAR(50),
    product VARCHAR(50),
    sales INT
);

接下来,我们在sales_table表中插入一些示例数据:

INSERT INTO sales_table (region, product, sales) VALUES     ('North', 'Product A', 100);
INSERT INTO sales_table (region, product, sales) VALUES     ('South', 'Product B', 200);
INSERT INTO sales_table (region, product, sales) VALUES     ('East', 'Product C', 300);
INSERT INTO sales_table (region, product, sales) VALUES     ('West', 'Product D', 400);
INSERT INTO sales_table (region, product, sales) VALUES     ('North', 'Product B', 500);
INSERT INTO sales_table (region, product, sales) VALUES     ('South', 'Product C', 600);
INSERT INTO sales_table (region, product, sales) VALUES     ('East', 'Product D', 700);
INSERT INTO sales_table (region, product, sales) VALUES     ('West', 'Product A', 800);

现在,我们可以使用GROUP BY的扩展操作来查询sales_table表中的数据。

  1. 使用ROLLUP操作

ROLLUP操作可以生成分层汇总报告,以便分析数据的不同维度,例如时间、地区、产品等。以下是一个ROLLUP操作的示例,该示例计算了不同地区和产品的销售总额:

SELECT region, product, SUM(sales) AS total_sales
FROM sales_table
GROUP BY ROLLUP(region, product);
  1. 使用CUBE操作

CUBE操作是ROLLUP的变种,可以生成组合式的汇总报告,可以对所有可能的组合进行聚合操作。以下是一个CUBE操作的示例,该示例计算了不同地区和产品的销售总额,但是不仅限于特定组合:

SELECT region, product, SUM(sales) AS total_sales
FROM sales_table
GROUP BY CUBE(region, product);
  1. 使用GROUPING SETS操作

GROUPING SETS操作类似于CUBE操作,但它仅生成指定的汇总组合。以下是一个GROUPING SETS操作的示例,该示例计算了不同地区和产品的销售总额,但仅限于特定的地区组合:

SELECT region, product, SUM(sales) AS total_sales
FROM sales_table
GROUP BY GROUPING SETS((region), (region, product));

以上就是SQL:1999中使用GROUP BY扩展操作的一些例子,这些扩展操作提供了更好的灵活性,以实现复杂的汇总报告需求。

5. SQL:2003

全称是“ISO/IEC 9075:2003”,是SQL标准的重要更新版本。它于2003年发布,是SQL:1999之后的更新版本,旨在进一步完善SQL的功能和语法。
其最重要的新增功能是OLAP 功能扩展,支持窗口函数,这些函数大大简化了对多维数据集进行复杂分析和汇总的过程。

窗口函数

以下是QL:2003中使用窗口函数操作的一个示例。

建表SQL:

CREATE TABLE sales (
    region VARCHAR(20),
    country VARCHAR(20),
    city VARCHAR(20),
    year INTEGER,
    month INTEGER,
    amount DECIMAL(10,2)
);

插入数据SQL:

INSERT INTO sales VALUES ('North America', 'USA', 'New York', 2020, 1, 1000.00);
INSERT INTO sales VALUES ('North America', 'USA', 'New York', 2020, 2, 1500.00);
INSERT INTO sales VALUES ('North America', 'USA', 'Los Angeles', 2020, 1, 2000.00);
INSERT INTO sales VALUES ('North America', 'USA', 'Los Angeles', 2020, 2, 2500.00);
INSERT INTO sales VALUES ('North America', 'Canada', 'Toronto', 2020, 1, 3000.00);
INSERT INTO sales VALUES ('North America', 'Canada', 'Toronto', 2020, 2, 3500.00);
INSERT INTO sales VALUES ('Europe', 'UK', 'London', 2020, 1, 4000.00);
INSERT INTO sales VALUES ('Europe', 'UK', 'London', 2020, 2, 4500.00);
INSERT INTO sales VALUES ('Europe', 'France', 'Paris', 2020, 1, 5000.00);
INSERT INTO sales VALUES ('Europe', 'France', 'Paris', 2020, 2, 5500.00);

查询SQL:

SELECT 
    region,
    country,
    city,
    year,
    month,
    amount,
    SUM(amount) OVER (PARTITION BY region, country ORDER BY year, month) AS running_total
FROM sales;

这个SQL语句计算了每个区域、国家、城市、年份、月份的销售总额,并且计算了每个区域、国家的销售总额随时间的变化(running_total)。

输出结果:

region          | country  | city        | year | month | amount   | running_total
----------------+----------+-------------+------+-------+----------+---------------
North America   | USA      | New York    | 2020 | 1     | 1000.00  | 1000.00
North America   | USA      | New York    | 2020 | 2     | 1500.00  | 2500.00
North America   | USA      | Los Angeles | 2020 | 1     | 2000.00  | 2000.00
North America   | USA      | Los Angeles | 2020 | 2     | 2500.00  | 4500.00
North America   | Canada   | Toronto     | 2020 | 1     | 3000.00  | 3000.00
North America   | Canada   | Toronto     | 2020 | 2     | 3500.00  | 6500.00
Europe          | UK       | London      | 2020 | 1     | 4000.00  | 4000.00
Europe          | UK       | London      | 2020 | 2     | 4500.00  | 8500.00
Europe          | France   | Paris       | 2020 | 1     | 5000.00  | 5000.00
Europe          | France   | Paris       | 2020 | 2     | 5500.00  | 10500.00

以上代码演示了窗口函数的使用,特别是“SUM(amount) OVER”,它使用“PARTITION BY”分割结果集,根据销售区域和国家分组,并按年月排序计算销售总额;“ORDER BY”指定聚合的顺序。

6. SQL:2006

SQL:2006全称是“ISO/IEC 9075:2006”。
SQL:2003引入了与XML相关的函数,允许数据库和XML技术之间的互操作。SQL:2006 定义了 SQL 操作 XML 的方式。

支持XML

以下是一个示例SQL脚本,用于创建一个表、插入XML数据并从中提取信息:

-- 创建一个 XML 类型表
CREATE TABLE book_table (
  id NUMBER PRIMARY KEY,
  title VARCHAR2(100),
  authors XMLTYPE,
  publication_date DATE,
  price NUMBER
);

-- 向表中插入一条XML数据
INSERT INTO book_table VALUES (
  1, 
  'XML Programming', 
  XMLTYPE('Jane DoeJohn Smith'), 
  TO_DATE('2021-06-10', 'YYYY-MM-DD'), 
  99.99
);

-- 从表中获取XML数据,并从中提取信息
SELECT 
  id, 
  title, 
  extractvalue(authors, '/authors/author[1]') AS author1, -- 提取第一个作者
  extractvalue(authors, '/authors/author[2]') AS author2, -- 提取第二个作者
  publication_date, 
  price
FROM 
  book_table;

在这个例子中,我们首先创建了一个名为 book_table 的表,它包含了 idtitleauthorspublication_dateprice 字段。其中 authors 字段使用 XMLType 类型来存储一个XML类型的数据,它包含了一组作者信息。
接着,我们向表中插入了一条数据,其中包含了XML类型的作者信息。
查询中,我们使用了 extractvalue 函数从 authors 字段中提取 XML 数据。extractvalue 函数需要两个参数:第一个是要提取的 XML 字符串,第二个是 XPath 表达式。在我们的查询中,我们使用 XPath 表达式 /authors/author[n] 提取作者信息,其中 n 是第几个作者的编号。注意,XPath 表达式中的索引从 1 开始,而不是从 0 开始。

通过对XML 的支持,使得 SQL 更加灵活和适应多样化的数据处理需求。

7. SQL:2008

SQL:2008新增了很多功能,下面是部分新增的功能及SQL说明例子。

7.1. 增强了MERGE和DIAGNOSTIC语句

MERGE语句用于将INSERT、UPDATE和DELETE操作组合成单个语句,提高了数据操作的效率和灵活性。DIAGNOSTIC语句则用于存储和返回SQL错误和警告信息,方便开发者进行调试。

-- MERGE语句
MERGE INTO Sales AS target
  USING (SELECT product_id, SUM(amount) AS total_sales
         FROM SalesDetail
         GROUP BY product_id) AS source (product_id, total_sales)
  ON (target.product_id = source.product_id)
  WHEN MATCHED THEN
    UPDATE SET total_sales = source.total_sales
  WHEN NOT MATCHED THEN
    INSERT (product_id, total_sales)
    VALUES (source.product_id, source.total_sales);

-- DIAGNOSTIC语句
BEGIN
  UPDATE Sales SET amount_sold = amount_sold + 1 WHERE product_id = 'P1';
EXCEPTION
  WHEN OTHERS THEN
    GET DIAGNOSTICS @error_num = DB2_RETURNED_SQLCODE,
                   @error_msg = MESSAGE_TEXT;
    RAISE NOTICE 'Error Code: %, Error Message: %', @error_num, @error_msg;
END;

7.2. 引入了TRUNCATE TABLE语句

TRUNCATE TABLE语句可以更快速地清空表数据,比DELETE语句效率更高。

TRUNCATE TABLE SalesDetail;

7.3. CASE表达式支持逗号分隔的WHEN子句

逗号分隔的WHEN子句可以让CASE表达式更加灵活,方便开发者进行条件判断。

SELECT CASE
         WHEN amount > 1000 THEN 'High'
         WHEN amount > 500 THEN 'Medium'
         ELSE 'Low'
       END AS sales_level
FROM Sales;

7.4. 引入了INSTEAD OF触发器

INSTEAD OF触发器可以在执行DML操作前触发一些自定义逻辑,更好地控制数据操作。

CREATE TRIGGER instead_of_insert_sales_detail
INSTEAD OF INSERT ON SalesDetail
FOR EACH ROW
BEGIN
  IF NEW.amount > 0 THEN
    INSERT INTO SalesDetail (product_id, amount)
    VALUES (NEW.product_id, NEW.amount);
  END IF;
END;

7.5. 支持JOIN分区表

JOIN分区表可以更好地管理分区表的数据,提高了数据查询和管理的效率。

SELECT *
FROM Sales s
JOIN SalesDetail sd ON s.id = sd.sales_id
WHERE s.date BETWEEN '2021-01-01' AND '2021-01-31';

7.6. 引入了FETCH子句

FETCH子句可以更加精确地控制数据检索结果,同时提升检索性能。

SELECT *
FROM Sales
ORDER BY date DESC
FETCH FIRST 10 ROWS ONLY;

7.7. 允许在游标定义之外使用ORDER BY

允许在游标定义之外使用ORDER BY,提供更加灵活的数据排序功能。

-- 游标定义
DECLARE cur_sales CURSOR FOR
  SELECT *
  FROM Sales;

-- 在游标之外使用ORDER BY
SELECT *
FROM Sales
ORDER BY date DESC;

7.8. 支持各种XQuery正则表达式/模式匹配

XQuery正则表达式/模式匹配可以更好地处理复杂的数据匹配需求。

SELECT *
FROM Sales
WHERE XMLCAST(XMLQUERY('$d/address' PASSING customer_doc AS "d") AS VARCHAR(200))
      LIKE '%CA%';

9. 派生字段名增强

派生字段名增强可以提供更加灵活的数据处理和分析能力。

SELECT product_id, amount, amount * price AS total_price
FROM SalesDetail;

8. SQL:2011

SQL:2011全称是"ISO/IEC 9075:2011", 最主要的新功能之一是增强了对时态数据库的支持,并对MERGE语句、窗口函数和FETCH子句等进行了一些改进。

下面是SQL代码,下面是部分新增的功能及SQL说明例子。

8.1. DELETE IN MERGE(在合并语句中使用删除)

DELETE IN MERGE语句可以同时执行合并操作和删除操作。下面的示例使用了一个名为emp(员工)的表格和另一个名为emp_old(旧员工)的表格,其中emp_old表格的记录需要从emp表格中删除。

MERGE INTO emp USING emp_old 
ON emp.emp_id=emp_old.emp_id 
WHEN MATCHED THEN DELETE;

上面代码中,MERGE INTO语句将emp_old表格中的记录合并到了emp表格中,当两个表格中的emp_id字段匹配时,将在emp表格中删除记录。

8.2. Pipeline DML(管道DML)

Pipeline DML是一种在客户端和服务器之间直接传输数据的方法,此方法可以更快地执行数据操作并减少对网络的依赖。下面的示例使用了PIPELINED关键字。

CREATE OR REPLACE FUNCTION process_emp_data (lname VARCHAR2) 
RETURN emp_type_table PIPELINED
IS
emp_data emp%ROWTYPE;
CURSOR c_emp_data IS 
  SELECT * FROM emp WHERE last_name = lname;
BEGIN 
  OPEN c_emp_data;
  LOOP 
    FETCH c_emp_data INTO emp_data;
    EXIT WHEN c_emp_data%NOTFOUND;
    ... --对记录进行处理 
    PIPE ROW(emp_data);
  END LOOP;
  CLOSE c_emp_data;
  RETURN; 
END;

上面代码中,我们定义了一个名为process_emp_data的函数,它可以按姓名(lname)返回emp表格中所有的记录。这个函数是PIPELINED的,这表示函数将返回多行记录,这些记录将被直接传输到客户端而不是在服务器端生成一个临时表格。

8.3. Limited Fetch Capability(有限的提取能力)

LIMITED FETCH语句可以限制在查询中返回的行数。下面的示例仅返回第一行记录。

SELECT * FROM emp FETCH FIRST ROW ONLY;

上面代码中,FETCH FIRST ROW ONLY语句告诉数据库在查询中只返回第一行记录。如果我们想要查询前10行记录,可以像下面这样写:

SELECT * FROM emp FETCH FIRST 10 ROWS ONLY;

上面代码中,FETCH子句指定了要返回的前10行记录。

8.4. 窗口函数增强

8.4.1. LAG和LEAD函数

LAG和LEAD函数是SQL:2011中新增的窗口函数,用于访问当前行之前或之后的行的数据。

SELECT employee_id, last_name, salary, LAG(salary) OVER (ORDER BY salary) AS prev_salary, 
LEAD(salary) OVER (ORDER BY salary) AS next_salary FROM employees;

上面代码中,我们使用了LAG和LEAD函数来获取当前员工的薪资及其前一个和后一个员工的薪资。我们使用了ORDER BY语句来按照薪资从低到高排序。

8.4.2. Navigation within a window

SQL:2011还引入了Navigation within a window,它允许用户在窗口内导航并进行计算。例如,我们可以使用ROW_NUMBER()函数来给每个员工分配一个数字,然后使用RANGE或ROWS子句指定窗口大小并识别一个员工的上下文。

SELECT employee_id, last_name, salary, 
AVG(salary) OVER (ORDER BY ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary)) AS avg_salary 
FROM employees;

上面代码中,我们将每个员工按工资排序,并以每个部门为分组设置窗口。然后,我们使用AVG窗口函数来计算排名上下文中员工的平均工资。

9. SQL:2016

全称是"ISO/IEC 9075:2016",增加了许多新特性,包括JSON支持、多种类型的表值函数、多列的基于匹配的搜索和分组集聚操作等特性。下面介绍其中的两个新功能:JSON支持和表值函数。

9.1. JSON支持

在2010年代,JSON逐渐取代XML成为常见的数据交换格式。现代互联网应用程序使用JSON而不是XML作为它们的数据格式。越来越多的数据库也开始支持JSON,例如文档数据库可以存储JSON文件,键值存储可以兼容JSON格式。

因此,SQL标准添加对JSON的支持,扩展了SQL的应用范围,也使得SQL可以更好地与现代应用程序以及基于JSON的数据库进行交互。这也让SQL更具有灵活性和可扩展性,可以处理越来越复杂的数据结构。

SQL:2016新增了对JSON(JavaScript Object Notation)格式的查询支持。它支持使用SQL语法处理JSON数据类型,这使得从JSON数据中读取和查询数据变得更加方便。

SELECT c.customer_id, JSON_VALUE(c.info, '$.address.city') AS city, 
JSON_VALUE(c.info, '$.address.state') AS state FROM customers c;

在上面的例子中,我们使用了JSON_VALUE函数来查询存储在JSON格式中的客户信息。我们指定了JSON路径($ .address.city和$ .address.state),并将正确的值提取出来,作为城市和州的名称。

9.2. 表值函数(Table-Valued Functions)

SQL:2016引入了表值函数的概念。它是一种特殊类型的存储过程,可以生成一个表作为结果。

CREATE FUNCTION getEmployees(@deptId INT) 
RETURNS TABLE AS RETURN 
SELECT employee_id, first_name, last_name FROM employees WHERE department_id = @deptId;

在上面的例子中,我们创建了一个名为getEmployees的表值函数。该函数接受一个整数参数,并返回一个包含指定部门中所有员工的表。

可以像查询表一样使用表值函数,例如:

SELECT * FROM getEmployees(10);

上面的查询将返回部门号为10的员工信息。这样的表值函数可以在作为子查询或联接的一部分使用,让查询更加灵活和高效。

10. SQL:2019

SQL:2019全称是"ISO/IEC 9075:2019",SQL:2019于2019年11月由国际标准化组织(ISO)和国际电工委员会(IEC)联合发布,是自2016年SQL:2016标准以来的第一次更新。

- 树形结构数据:SQL:2019标准支持使用标准的SQL语句处理和查询树形结构数据,例如组织结构、目录和分类等。
- 增强的空间数据支持:SQL:2019标准引入了用于存储和查询空间数据(如地理位置数据)的新数据类型、函数和操作符。
- 字符集扩展:SQL:2019标准引入了对日文和韩文等字符集的扩展支持。
- 新的分析功能:SQL:2019标准添加了新的分析功能,例如累积分布函数、指数平滑等。
- 改进的JSON支持:SQL:2019标准在前一版本的JSON支持基础上进行改进,包括更多的功能和更规范的语法。
此外,SQL:2019标准还修复了一些早期版本的漏洞和不一致性,提高了数据库的安全性和可靠性。

多维数组(SQL/MDA)

该标准引入了一些新的功能和改进,其中最显著的是多维数组(SQL/MDA)支持。多维数组是一个在行和列之外添加一个指定数量的维度的数据结构,通常在数据仓库和数据分析中使用。SQL/MDA的引入使SQL可以更有效地处理多维数据,例如:网络数据、传感器数据、图像和视频数据等。

  1. 创建多维数组
    在SQL:2019标准中,可以使用以下语法创建多维数组:
CREATE ARRAY <array name> [ <array specification> ]

例如,以下SQL代码创建一个具有三个维度的数组:

CREATE ARRAY my_array [3, 4, 5];
  1. 插入数组数据
    使用以下语法向数组中插入数据:
INSERT INTO <array name> [(<dimension list>)] VALUES (<value list>)

例如,以下SQL代码插入了一些数据到多维数组中:

INSERT INTO my_array[2, 3, 4] VALUES ('Test data');

3.查询数组数据
使用以下语法查询数组中的数据:

SELECT <expression> FROM <array name> [(<dimension specification>)]

例如,以下SQL代码查询了my_array中第三个维度所有为4的数据:

SELECT * FROM my_array[ , , 4];

SQL:2019新功能-多维数组的引入扩展了SQL在数据分析和处理上的功能,使得SQL在处理更加复杂和多维数据结构时更加高效和灵活。

总结

SQL标准是一系列定义了关系型数据库管理系统所应遵循的规范和标准,包括SQL-86、SQL-89、SQL-92、SQL:1999、SQL:2003、SQL:2008、SQL:2011、SQL:2016和SQL:2019等多个版本。其重点是提供一种统一的语言,用于在关系型数据库中访问和操作数据。SQL标准包括数据定义、数据操作、数据查询、数据控制和事务管理等方面内容,以及定义了一系列的数据类型、函数、操作符等各种元素,这些元素能够在不同的实现中进行通用性的应用。SQL标准的实现是不同的数据库管理系统的重要基础,也是数据处理的重要工具之一。

参考

https://learnsql.com/blog/history-of-sql-standards/
https://blog.ansi.org/2018/10/sql-standard-iso-iec-9075-2016-ansi-x3-135/
https://docs.oracle.com/en/database/oracle/oracle-database/18/sqlrf/Oracle-and-Standard-SQL.html
https://www.wiscorp.com/SQLStandards.html
https://sigmodrecord.org/publications/sigmodRecord/1209/pdfs/07.industry.kulkarni.pdf
https://crate.io/docs/sql-99/en/latest//index.html
https://modern-sql.com/blog/2017-06/whats-new-in-sql-2016
https://zhuanlan.zhihu.com/p/110882130
http://peter.eisentraut.org/blog/2023/04/04/sql-2023-is-finished-here-is-whats-new

你可能感兴趣的:(SQL,SQL全方位攻略,sql,数据库,java)