PartiQL 对 SQL 的扩展,可以查询非结构化的数据

2023-05-16

目录

开始

先决条件

下载 PartiQL CLI

运行 PartiQL CLI

窗户

macOS (Mac) 和 Unix

命令行教程

介绍

PartiQL 查询与 SQL 兼容

PartiQL 数据模型:许多底层数据存储格式的抽象

了解更多信息

查询嵌套数据

嵌套集合

取消嵌套嵌套集合

了解更多信息

使用 取消嵌套嵌套集合JOIN

使用 LEFT JOIN 取消嵌套数据始终保留父信息

用例:检查嵌套集合是否满足条件

用例:聚合嵌套集合的子查询

嵌套元组值和多步骤路径

取消嵌套任意形式的嵌套集合

用例:取消嵌套标量数组

用例:取消嵌套数组的数组

文字

查询异构和无模式数据

缺少属性的元组

访问和处理缺失属性:缺失值

评估缺少的功能和条件

在结果元组中传播缺失

变量的范围可以超过不同类型的数据

按顺序访问数组元素

[]

多步骤路径

查找数组中每个元素的索引

旋转和取消旋转

取消枢轴元组

旋转到元组

用例:旋转子查询

创建嵌套和非 SQL 结果

使用查询创建嵌套结果SELECT VALUE

创建嵌套结果GROUP BY ... GROUP AS

了解有关 PartiQL 的更多信息


开始

PartiQL 提供了一个交互式 shell,允许用户编写和评估 PartiQL 查询。

先决条件

PartiQL 要求在您的计算机上安装 Java 运行时 (JVM)。 您可以从以下任一位置获取最新版本的 Java 运行时

  1. OpenJDK或适用于Windows的OpenJDK

  2. 神谕

按照有关如何设置到 Java 运行时安装路径的说明进行操作。JAVA_HOME

下载 PartiQL CLI

每个版本的 PartiQL 都附带一个存档,其中包含 PartiQL CLI 作为 压缩文件。

  1. 下载。 您可能需要单击才能查看zip和tgz存档。 最新的 zip 存档到您的计算机。Assets``partiql-cli

  2. 展开(解压缩)计算机上的存档。展开存档将生成以下文件夹结构:

该文件会将 PartiQL 的发布版本附加到存档中,即 .partiql-cli-0.1.0.zip


├── partiql-cli
    ├── bin
    │   ├── partiql
    │   └── partiql.bat
    ├── lib
    │   └── ... 
    ├── README.md
    └── Tutorial
        ├── code
        │   └── ... 
        ├── tutorial.html
        └── tutorial.pdf  

其中表示省略的文件/目录。...

根文件夹包含一个文件和 3 个子文件夹partiql-cli``README.md

  1. 该文件夹包含适用于 macOS 的启动脚本和 Unix 系统和 Windows 系统。执行这些文件 以启动 REPL。bin``partiql``partiql.bat

  2. 该文件夹包含运行 PartiQL 所需的所有必需的 Java 库。lib

  3. 该文件夹包含教程和表单。子文件夹包含 3 种类型的文件:

    
    Tutorial  
    
    pdf  
    
    html  
    
    code  
    1. 扩展名为 的数据文件 .这些文件包含 PartiQL 我们可以查询的数据。.env

    2. 扩展名为 的 PartiQL 查询文件 .这些文件包含 本教程中使用的 PartiQL 查询。.sql

    3. 扩展名为 的示例查询输出文件 .这些文件 包含运行教程查询的示例输出 适当的数据。.output

    4. 或者,您可以使用在线 CLI 教程。

运行 PartiQL CLI

窗户

运行(双击)。这应该打开一个命令行 提示并启动 PartiQL Shell,其中显示:partiql.bat


Welcome to the PartiQL shell!  

macOS (Mac) 和 Unix

  1. 打开终端并导航到该文件夹。partiql-cli

  2. 通过键入并按 Enter 启动 REPL,其中显示:./bin/partiql

文件夹名称将以 PartiQL 版本作为后缀,即 .partiql-cli-0.1.0


Welcome to the PartiQL shell!  

命令行教程

要更深入地了解 PartiQL,请查看 CLI 教程。

介绍

PartiQL 提供跨多个 SQL 兼容的统一查询访问 包含结构化、半结构化和嵌套数据的数据存储。 PartiQL 分离了 从基础数据源和数据格式查询。 它使用户能够在有或没有的情况下与数据进行交互 常规架构。

该实现目前仅支持没有 图式。即将推出架构支持。

本教程旨在教SQL用户SQL的PartiQL扩展。这 教程主要由“操作方法”示例驱动。

对于对完整细节和正式感兴趣的读者 PartiQL 的规范,我们建议使用 2 层 PartiQL 正式 规范:正式规范首先描述 PartiQL 核心,它是一种简短而简洁的函数式编程语言。 然后规范通过语法糖层 SQL 兼容性 展示了如何将SQL功能转换为语义等效的 核心 PartiQL 表达式。这些翻译以句法糖的形式呈现 启用 SQL 兼容性。

PartiQL 查询与 SQL 兼容

PartiQL 向后兼容 SQL-92。我们将看到什么 兼容性是指当它用于查询在数据格式中找到的数据时 和数据存储。

SQL-92

对于初学者,给定表格hr.employees


  Id             name          title
  -------------- ------------- ----------------
  3              Bob Smith     null
  4              Susan Smith   Dev Mgr
  6              Jane Smith    Software Eng 2  

以下 SQL 查询


SELECT e.id, 
       e.name AS employeeName, 
       e.title AS title
FROM hr.employees e
WHERE e.title = 'Dev Mgr'  

也是一个有效的 PartiQL 查询。正如我们从SQL中知道的那样,当这个查询 在表上运行,它将返回结果hr.employees


  Id   employeeName   title
  ---- -------------- ---------
  4    Susan Smith    Dev Mgr  

信息

为方便起见,我们在文件夹中提供了该文件。您还将在同一文件夹中找到单独的文件 对于教程中的每个查询。tutorial-all-data.env``Tutorial/code/``.env

例如,跑步


./bin/partiql  -e .wiki/assets/code/tutorial-all-data.env  

将在 REPL 中加载本教程中使用的所有数据。这将 允许您将教程中的查询复制粘贴到 REPL 中并尝试 他们出来了。

PartiQL 数据模型:许多底层数据存储格式的抽象

PartiQL 不仅对 SQL 表进行操作,还对数据进行操作 可能具有嵌套、联合类型、不同的属性 不同的元组,以及我们在今天的 嵌套和/或半结构化格式,如 JSON、Ion、Parquet 等。

为了捕获这种通用性,PartiQL 基于逻辑类型系统: PartiQL 数据模型。每个 PartiQL 实现映射数据格式, 像 JSON、Parquet 等一样,放入遵循 PartiQL 的 PartiQL 数据集中 数据模型。PartiQL 查询处理 PartiQL 数据集抽象。

例如,该表在 PartiQL 数据中表示 建模为此数据集hr.employees


{ 
    'hr': { 
        'employees': <<
            -- a tuple is denoted by { ... } in the PartiQL data model
            { 'id': 3, 'name': 'Bob Smith',   'title': null }, 
            { 'id': 4, 'name': 'Susan Smith', 'title': 'Dev Mgr' },
            { 'id': 6, 'name': 'Jane Smith',  'title': 'Software Eng 2'}
        >>
    }
}   

请注意,嵌套在 中。 分隔符... 表示数据 是一个无序集合(也称为 bag),情况就是如此 与 SQL 表。也就是说,三个元组之间没有顺序。 单行注释以行尾开头,结束于行尾。employees``hr``<<``>>``--

一种非常不同类型的数据源可能会导致相同的 PartiQL 数据。例如,一组包含以下内容的 JSON 文件 JSON 对象


{ 
    "hr" : { 
        "employees": [
            { "id": 3, "name": "Bob Smith",   "title": null },
            { "id": 4, "name": "Susan Smith", "title": "Dev Mgr" },
            { "id": 6, "name": "Jane Smith",  "title": "Software Eng 2"}
        ]
    }
}  

可能会被支持 PartiQL 的 实现到与表相同的 PartiQL 抽象中。hr.employees

附加到的 JSON 值是一个有序列表。PartiQL 实现可以提供自己的映射,来自流行的 数据格式,例如CSV,TSV,JSON,Ion等,到PartiQL数据模型和/或允许客户端 以实现自己的映射。employee

备注:你会不断注意到PartiQL的相似性 表示法和 JSON 表示法。还要注意细微的差异: 在 SQL兼容性的兴趣,PartiQL文字是单引号,而 JSON 文本是双引号的。

备注:您可能从概念上认为反序列化程序输入 JSON 并输出 PartiQL 数据集。但不要假设查询 PartiQL 实现的处理必须实际解析和 将底层数据存储的每一比特抽象为 PartiQL。

回到我们的查询


SELECT e.id, 
       e.name AS employeeName, 
       e.title AS title
FROM hr.employees e
WHERE e.title = 'Dev Mgr'  

在 PartiQL 中计算查询将生成:


<<
  {
    'id': 4,
    'employeeName': 'Susan Smith',
    'title': 'Dev Mgr'
  }
>>
--- 
OK!  

结果保持不变,无论是否 SQL 表或 JSON 文件。所需要的只是一个 名称与 PartiQL 抽象之间的关联 数据。hr.employees``hr.employees

本着同样的精神,相同的PartiQL抽象可能来自CSV。 文件或镶木地板文件,这种格式获得了很大的吸引力,这要归功于 存储数据的有效方式。同样,相同的查询使 完美的感觉,无论背后的存储格式到底是什么。hr.employees

了解更多信息

  • PartiQL 数据集看起来非常像 JSON。

    有什么区别?事实上,PartiQL 采用了元组/对象和数组 JSON 的表示法。但是,PartiQL 字符串文本表示 用单引号。重要的是,PartiQL 的标量类型是那些 SQL,而不仅仅是字符串,数字和布尔值,如JSON。

  • 实现是否需要具有目录?

    如果查询引用 名称,目录在逻辑上验证名称是否存在。 但是,我们还将看到不引用名称的 PartiQL 查询。

查询嵌套数据

SQL-92 仅具有具有包含标量值的元组的表。一把钥匙 许多现代格式的特征是嵌套数据。也就是说,属性 值本身可以是表(即元组的集合),也可以是 标量数组,或数组数组和许多其他组合。让我们 仔细看看 PartiQL 的功能(SQL 扩展),这些功能允许我们 以使用嵌套数据。

我们还包括标题为“用例”的部分。此类“用例”部分不会 引入其他功能。他们只是展示了如何结合 一些具有标准SQL功能的新颖PartiQL功能,以便 解决大量问题。

嵌套集合

现在让我们将嵌套属性添加到数据集中。projects


{ 
  'hr': { 
      'employeesNest': <<
         { 
          'id': 3, 
          'name': 'Bob Smith', 
          'title': null, 
          'projects': [ { 'name': 'AWS Redshift Spectrum querying' },
                        { 'name': 'AWS Redshift security' },
                        { 'name': 'AWS Aurora security' }
                      ]
          },
          { 
              'id': 4, 
              'name': 'Susan Smith', 
              'title': 'Dev Mgr', 
              'projects': [] 
          },
          { 
              'id': 6, 
              'name': 'Jane Smith', 
              'title': 'Software Eng 2', 
              'projects': [ { 'name': 'AWS Redshift security' } ] 
          }
      >>
    }
}  

请注意,的值是一个数组。数组用逗号分隔的数组元素表示。在我们的示例中,数组 恰好是一个元组数组。我们将看到数组可能是数组 任何东西,而不仅仅是元组数组。'projects'``[ ... ]

取消嵌套嵌套集合

以下查询查找处理包含以下内容的项目的员工的姓名 字符串并输出它们以及项目名称。请注意,查询只有一个扩展名 超过标准 SQL ---部分。'security'``'security'``e.projects AS p


SELECT e.name AS employeeName, 
       p.name AS projectName
FROM hr.employeesNest AS e, 
     e.projects AS p
WHERE p.name LIKE '%security%'  

我们查询的输出是


<<
  {
    'employeeName': 'Bob Smith',
    'projectName': 'AWS Redshift security'
  },
  {
    'employeeName': 'Bob Smith',
    'projectName': 'AWS Aurora security'
  },
  {
    'employeeName': 'Jane Smith',
    'projectName': 'AWS Redshift security'
  }
>>
--- 
OK!  

SQL 的扩展是子句项。 标准 SQL 会尝试查找以表命名的架构,由于在我们的示例中没有表,因此查询将失败。相反,PartiQL 识别为引用 的属性。FROM``e.projects AS p``e``projects``e.projects``e.projects``projects``e

一旦我们允许这个扩展,语义就是类似的SQL。别名 (在 PartiQL 中也称为变量)绑定到每个员工,在 转。对于每个员工,变量绑定到每个 反过来,员工的项目。因此,查询的含义,如 SQL, 是e``p

Foreach 员工元组来自 Foreach 项目元组来自 if 输出e``hr.employeesNest``p``e.projects``p.name LIKE '%security%'``e.name AS employeeName, p.name AS projectName

请注意,我们的查询涉及的变量范围超过嵌套 集合(在示例中),以及 范围超过表(在示例中),就像标准 SQL 别名一样。 所有变量,无论它们的范围如何,都可以在任何地方使用 我们将在下面的示例中看到的 、 子句。p``e``FROM``WHERE``SELECT

了解更多信息

  • 我只能取消嵌套元组数组吗?

    不,任何东西都可以取消嵌套。 例如,标量数组等。

  • e.projects AS p 是否必须出现在相同的 FROM 子句中 这定义了E

    不。例如,请参阅下面的用例 涉及子查询。在那里,和在 单独的条款。e``p``FROM

  • 如何强制 e.projects 引用嵌套属性项目,即使有一个名为 e 的架构和表项目?``

    使用语法 。回想一下,在 缺少 ,为了 SQL 兼容性,PartiQL 将首先尝试取消引用 目录。@e.projects``@``e.projects

  • SQL允许我在编写时避免编写显式别名e, 说,e.name。我也可以避免在 PartiQL 中写 e 吗?

    SQL允许我们避免在模式 这些表允许正确的取消引用。PartiQL 也这样做。 但是,回想一下,PartiQL 数据集不需要架构。 事实上,我们的示例没有假设模式。缺席的情况下 在架构中,不能省略别名(变量)。例如 如果你只写,没有模式,PartiQL 不能 告诉您是指员工姓名还是项目名称。因此,您需要 显式写入别名(变量)。name

    此规则有一个例外:如果您的查询包含单个项目 在其子句中,可以省略别名(变量)。例如,你 可以写FROM

    
    SELECT name FROM hr.employeesNest  

    在这种情况下,很明显可能只是员工 名称,因此 PartiQL 允许您不提供别名(变量)。name

    不过,为清楚起见,我们建议您始终使用别名 (变量),这就是本教程的作用。

  • 如果有模式,我可以避免写入别名 p 吗?

    不。必须编写以表示迭代 项目。p

使用 取消嵌套嵌套集合JOIN

在本节中,我们只是介绍另一种表达和思考的方式 关于取消嵌套集合。

有人可能会认为 从某种意义上说,示例在员工和项目之间执行 A。 如果它可以帮助您从 的角度思考,您可以替换逗号 跟。也就是说,以下两个查询是等效的。FROM``JOIN``JOIN``JOIN


+-----------------------------------+-----------------------------------------+
| SELECT e.name AS employeeName,    | SELECT e.name AS employeeName,          |
|        p.name AS projectName      |        p.name AS projectName            |
| FROM hr.employeesNest AS e,       | FROM hr.employeesNest AS e CROSS JOIN   |
|      e.projects AS p              |      e.projects AS p                    |
| WHERE p.name LIKE '%security%'    | WHERE p.name LIKE '%security%'          |
+-----------------------------------+-----------------------------------------+  

使用 LEFT JOIN 取消嵌套数据始终保留父信息

假设我们要编写一个查询,该查询以一袋 从 中元组整个员工和项目信息。我们想要的查询结果是这袋元组 带有属性、 和 :hr.employeesNest``id``employeeName``title``projectName


<<
  {
    'id': 3,
    'employeeName': 'Bob Smith',
    'title': NULL,
    'projectName': 'AWS Redshift Spectrum querying'
  },
  {
    'id': 3,
    'employeeName': 'Bob Smith',
    'title': NULL,
    'projectName': 'AWS Redshift security'
  },
  {
    'id': 3,
    'employeeName': 'Bob Smith',
    'title': NULL,
    'projectName': 'AWS Aurora security'
  },
  {
    'id': 4,
    'employeeName': 'Susan Smith',
    'title': 'Dev Mgr'
  },
  {
    'id': 6,
    'employeeName': 'Jane Smith',
    'title': 'Software Eng 2',
    'projectName': 'AWS Redshift security'
  }
>>
--- 
OK!  

请注意,结果中有一个元组,尽管 事实上,苏珊没有项目。苏珊的。 我们可以通过使用运算符将员工和项目组合在一起来获得此结果,如下所示:'Susan Smith'``projectName``null``LEFT JOIN


SELECT e.id AS id, 
       e.name AS employeeName, 
       e.title AS title, 
       p.name AS projectName
FROM hr.employeesNest AS e LEFT JOIN e.projects AS p ON true  

此查询的语义可以认为是


 foreach employee tuple `e` from `hr.employeesNest`
     if the `e.projects` is an empty collection then *// this part is special about LEFT JOINs*
         output `e.id AS id`, `e.name AS employeeName`, `e.title AS title`
         and output a `null AS projectName`
     else *// the following part is identical to plain (inner) JOINs*
         foreach project tuple `p` from `e.projects`
             output `e.id AS id`, `e.name AS employeeName`, `e.title AS title`  

用例:检查嵌套集合是否满足条件

以下用例使用了我们所拥有的非嵌套功能 已经在新的用例中讨论过。出现的一个教训是,我们 可以使用范围超过嵌套数据的变量(SQL 别名),就好像它们是 标准 SQL 别名。这种认识给了我们解决的能力 仅通过组合非嵌套功能即可获得大量用例 具有我们已经从标准SQL中了解的功能。

在我们的第一个用例中,我们想要一个返回 参与包含单词的项目的员工。该解决方案采用 SQL 的“(子查询)” 功能,以及取消嵌套:'security'``EXISTS


SELECT e.name AS employeeName
FROM hr.employeesNest AS e
WHERE EXISTS ( SELECT *
               FROM e.projects AS p
               WHERE p.name LIKE '%security%')  

返回


<<
  {
    'employeeName': 'Bob Smith'
  },
  {
    'employeeName': 'Jane Smith'
  }
>>
--- 
OK!  

在第二个用例中,我们想要一个输出 拥有多个安全项目的员工,以及 我们知道员工的键(例如,属性 保证每个员工都有唯一的价值)。 我们可以通过使用 和 的组合来找到所需的员工。在我们的示例中,假设该属性是雇员的主键。然后我们可以找到 具有多个安全项目的员工具有以下查询:GROUP BY``HAVING``id

我们也可以将运算符与子查询的结果一起使用,但是当前实现的问题阻止了我们这样做。>


SELECT e.name AS employeeName
FROM hr.employeesNest e, 
     e.projects AS p
WHERE p.name LIKE '%security%'
GROUP BY e.id, e.name
HAVING COUNT(*) > 1  

返回


<<
  {
    'employeeName': 'Bob Smith'
  }
>>
--- 
OK!  

用例:聚合嵌套集合的子查询

接下来,让我们找出有多少个查询项目(即其 名称包含“查询”一词)每个员工都有。

做出和以前一样的假设,这是员工的关键,我们可以解决 查询的问题id


SELECT e.name AS employeeName, 
       COUNT(p.name) AS queryProjectsNum
FROM hr.employeesNest e LEFT JOIN e.projects AS p ON p.name LIKE '%querying%'
GROUP BY e.id, e.name  

返回


<<
  {
    'employeeName': 'Bob Smith',
    'queryProjectsNum': 1
  },
  {
    'employeeName': 'Susan Smith',
    'queryProjectsNum': 0
  },
  {
    'employeeName': 'Jane Smith',
    'queryProjectsNum': 0
  }
>>
---
OK!  

请注意,此查询的结果包括 Susan Smith 和 Jane Smith,他们没有 查询项目。

嵌套元组值和多步骤路径

值也可以是元组 - 在许多中也称为对象和结构 模型和格式。例如,以下项目中的项目值 元组始终是具有项目名称和项目组织的元组。


{ 
    'hr': { 
        'employeesWithTuples': << 
            { 
                'id': 3, 
                'name': 'Bob Smith', 
                'title': null, 
                'project': { 
                    'name': 'AWS Redshift Spectrum querying', 
                    'org': 'AWS' 
                }
            },
            {
                'id': 6, 
                'name': 'Jane Smith', 
                'title': 'Software Eng 2', 
                'project': { 
                    'name': 'AWS Redshift security', 
                    'org': 'AWS' 
                }
            }
         >>
    }
}   

PartiQL 的多步骤路径支持在元组内导航。例如 以下查询查找 AWS 项目并输出项目名称和 员工姓名。


SELECT e.name AS employeeName, 
       e.project.name AS projectName
FROM hr.employeesWithTuples e
WHERE e.project.org = 'AWS'  

结果是


<<
  {
    'employeeName': 'Bob Smith',
    'projectName': 'AWS Redshift Spectrum querying'
  },
  {
    'employeeName': 'Jane Smith',
    'projectName': 'AWS Redshift security'
  }
>>
--- 
OK!  

取消嵌套任意形式的嵌套集合

前面的示例显示了嵌套属性,这些属性是数组 元组。嵌套属性不一定是 元组的集合。它们也可能只是标量数组, 数组的数组,或数据的任意组合 可以通过组合标量、元组和数组来创建。你不需要学习 每种情况都有不同的查询语言功能集。解嵌套 我们已经看到的功能就足够了。

用例:取消嵌套标量数组

与每个员工关联的项目列表可能只是项目名称的列表 字符串。用普通字符串替换嵌套元组给了我们hr.employeesNest


{ 
    'hr': { 
        'employeesNestScalars': <<
            { 
                'id': 3, 
                'name': 'Bob Smith', 
                'title': null, 
                'projects': [ 
                    'AWS Redshift Spectrum querying',
                    'AWS Redshift security',
                    'AWS Aurora security'
                ]
            },
            { 
                'id': 4, 
                'name': 'Susan Smith', 
                'title': 'Dev Mgr', 
                'projects': []
            },
            { 
                'id': 6, 
                'name': 'Jane Smith', 
                'title': 'Software Eng 2', 
                'projects': [ 'AWS Redshift security' ]
            }
        >>
    } 
}  

让我们在修订后的员工数据上重复前面的用例。

以下查询查找从事项目的员工的姓名 包含字符串并将它们与名称一起输出 的“安全”项目。'security'


SELECT e.name AS employeeName, 
       p AS projectName
FROM hr.employeesNestScalars AS e, 
     e.projects AS p
WHERE p LIKE '%security%'  

前面的查询返回


<<
  {
    'employeeName': 'Bob Smith',
    'projectName': 'AWS Redshift security'
  },
  {
    'employeeName': 'Bob Smith',
    'projectName': 'AWS Aurora security'
  },
  {
    'employeeName': 'Jane Smith',
    'projectName': 'AWS Redshift security'
  }
>>
--- 
OK!  

变量范围(再次)超过 的内容。在 这种情况,由于有字符串(与元组相反),因此 变量每次绑定到项目名称字符串。因此,这 可以将查询视为执行以下代码片段。p``e.projects``e.projects``p


 foreach employee tuple `e` from `hr.employeesNestScalars`
     foreach project `p` from `e.projects`
         if the string `p` matches `'%security%'`
           output `e.name AS employeeName` and the string `p AS projectName`  

用例:取消嵌套数组的数组

数组也可以直接包含数组,而不干预元组,如 在数据集中。matrices


{ 
    'matrices': <<
        { 
            'id': 3, 
            'matrix': [ 
                [2, 4, 6],
                [1, 3, 5, 7],
                [9, 0]
            ]
        },
        { 
            'id': 4, 
            'matrix': [ 
                [5, 8],
                [ ]
            ]
            
        }
    >>
}  

以下查询查找每个偶数并输出偶数 以及发现它的元组。id


SELECT t.id AS id, 
       x AS even
FROM matrices AS t, 
     t.matrix AS y,
     y AS x
WHERE x % 2 = 0  

前面的查询返回


<<
  {
    'id': 3,
    'even': 2
  },
  {
    'id': 3,
    'even': 4
  },
  {
    'id': 3,
    'even': 6
  },
  {
    'id': 3,
    'even': 0
  },
  {
    'id': 4,
    'even': 8
  }
>>
--- 
OK!  

非正式地,可以将查询的评估视为


 foreach tuple `t` from `matrices`
     foreach array `y` from `t.matrix`
         foreach number `x` from `y`
             if `x` is even then
                 output `t.id AS id` and `x AS even`  

文字

PartiQL 查询语言的文本对应于 PartiQL 数据模型:

  • 标量,包括遵循 SQL 语法的标量,包括以下 适用。例如:null

    • 5

    • 'foo'

  • 元组,用元组元素表示,由 (也称为结构和/或对象 多种格式和其他数据模型){...}``,

    • { 'id' : 3, 'arr': [1, 2] }

  • 数组,用数组元素表示[...]``,

    • [ 1, 'foo' ]

  • 袋子,用袋子元素表示,由<< ... >>``,

    • << 1, 'foo'>>

请注意,本着 PartiQL 数据模型的精神,文本组成 自由和任何类型的文字可以出现在任何元组、数组和 袋字面,例如,


{ 
    'id': 3, 
    'matrix': [ 
        [2, 4, 6],
        'NA'
    ]
}  

查询异构和无模式数据

许多格式不需要描述数据的模式,即无模式数据。在这种情况下,可以有各种 数据中的“异质性”:

  • 一个元组可能具有属性,而另一个元组可能没有 此属性x

  • 在集合的一个元组中,属性可能是一种类型,例如, 字符串,而在同一集合的另一个元组中相同 属性可以是不同的类型 - 例如,数组。x``x

  • 集合的元素(无论是包还是数组)可以是异构的(没有 相同类型)。例如,第一个元素可能是一个字符串,即 第二个可以是整数,第三个可以是数组。

  • 一般来说,任何组合都是可能的,因为我们可以捆绑 阵列和袋中的异构元素。

异构性并非无架构所特有的。架构可能允许 数据类型的异构性。例如,其中一个配置单元 数据类型是联合类型,它允许值属于 类型列表。考虑以下架构,其属性可能是 字符串或字符串数组projects

配置单元联合类型


CREATE TABLE employeesMixed(
        id: INT,
        name: STRING,
        title: STRING,
        projects: UNIONTYPE<STRING, ARRAY<STRING>>
);  

遵循此架构的 PartiQL 元组集合可以是


{ 
    'hr': { 
        'employeesMixed1': <<
            { 
                'id': 3, 
                'name': 'Bob Smith', 
                'title': null, 
                'projects': [ 
                    'AWS Redshift Spectrum querying',
                    'AWS Redshift security',
                    'AWS Aurora security'
                ]
            },
            { 
                'id': 4, 
                'name': 'Susan Smith', 
                'title': 'Dev Mgr', 
                'projects': [] 
            },
            { 
                'id': 6, 
                'name': 'Jane Smith', 
                'title': 'Software Eng 2', 
                'projects': 'AWS Redshift security' 
            }
        >>
    }
}  

因此,我们看到数据可能具有异质性---无论是否 它们是否由架构描述。PartiQL 解决异构问题 数据,我们将在下一个用例和功能中看到 介绍。

缺少属性的元组

让我们回到桌子(即元组袋)。 Bob Smith 没有标题,正如 SQL 中的典型情况一样,缺少标题是 使用值建模。hr.employees``null


{ 
    'hr': { 
        'employees': <<
            { 'id': 3, 'name': 'Bob Smith',   'title': null }
            { 'id': 4, 'name': 'Susan Smith', 'title': 'Dev Mgr' }
            { 'id': 6, 'name': 'Jane Smith',  'title': 'Software Eng 2'}
        >>
    }
}  

如今,许多半结构化格式允许用户表示 以两种方式“丢失”信息。

  1. 第一种方法是使用 .null

  2. 第二种是属性的明显缺失 元。

也就是说,我们可以表示鲍勃·史密斯没有头衔的事实 只需在元组中没有属性:title``'Bob Smith'


{ 
    'hr': {
        'employeesWithMissing': <<
            { 'id': 3, 'name': 'Bob Smith' }, -- no title in this tuple
            { 'id': 4, 'name': 'Susan Smith', 'title': 'Dev Mgr' },
            { 'id': 6, 'name': 'Jane Smith', 'title': 'Software Eng 2'}
        >>
    }
}   

PartiQL 不争论何时使用 s 以及何时使用 “失踪”。无数数据集已经使用两者之一或两者之一。 但是,PartiQL 使查询能够区分 null 和 缺失值,并且还启用具有 null 和 缺失值。事实上,PartiQL 使得传播源代码变得非常容易。 数据空作为查询结果空和源数据缺少属性进入 结果缺少属性。null

访问和处理缺失属性:缺失值

再次考虑这个PartiQL查询,它恰好也是一个SQL 查询。


SELECT e.id, 
       e.name AS employeeName, 
       e.title AS title
FROM hr.employeesWithMissing AS e
WHERE e.title = 'Dev Mgr'  

当查询经过鲍勃·史密斯元组时会发生什么,该元组具有 不?title

回答这个问题的第一步是了解 别名(变量)绑定到元组时的路径。用更基本的术语来说,什么是 表达式的结果 ? PartiQL说这是特殊价值。 行为与 非常相似。e.title``e``{ 'id': 3, 'name': 'Bob Smith' }``{ 'id': 3, 'name': 'Bob Smith' }.title``MISSING``MISSING``null

评估缺少的功能和条件

如果一个函数(包括中缀函数,如 )输入一个函数的结果是 。在本例中, 这意味着该条款将评估 当绑定到 和 时,像在 SQL 中一样,当它不绑定时,子句失败 评估为 。因此,输出将是=``MISSING``NULL``WHERE``e.title='Dev Mgr'``NULL``e``{ 'id': 3, 'name': 'Bob Smith' }``WHERE``true


<<
  {
    'id': 4,
    'employeeName': 'Susan Smith',
    'title': 'Dev Mgr'
  }
>>
--- 
OK!  

在结果元组中传播缺失

如果缺少属性,或者更一般地说,如果缺少属性,会发生什么情况 返回表达式出现在 ?MISSING``SELECT


SELECT e.id, 
       e.name AS employeeName,
       e.title AS outputTitle
FROM hr.employeesWithMissing AS e  

查询将为每个员工输出一个元组。当它输出 鲍勃·史密斯元组,将评估到然后 输出元组将没有属性。e.title``NULL``outputTitle


<<
  {
    'id': 3,
    'employeeName': 'Bob Smith'
  },
  {
    'id': 4,
    'employeeName': 'Susan Smith',
    'outputTitle': 'Dev Mgr'
  },
  {
    'id': 6,
    'employeeName': 'Jane Smith',
    'outputTitle': 'Software Eng 2'
  }
>>
--- 
OK!  

同样的处理也会发生,比如说,如果我们有这个 将标题转换为大写字母的查询:MISSING


SELECT e.id, 
       e.name AS employeeName, 
       UPPER(e.title) AS outputTitle
FROM hr.employeesWithMissing AS e  

同样,将计算为 for ,然后 是 并且还评估为 。 因此,结果将是:e.title``MISSING``'Bob Smith'``UPPER(e.title)``UPPER(MISSING)``NULL


<<
  {
    'id': 3,
    'employeeName': 'Bob Smith',
    'outputTitle': NULL
  },
  {
    'id': 4,
    'employeeName': 'Susan Smith',
    'outputTitle': 'DEV MGR'
  },
  {
    'id': 6,
    'employeeName': 'Jane Smith',
    'outputTitle': 'SOFTWARE ENG 2'
  }
>>
--- 
OK!  

变量的范围可以超过不同类型的数据

PartiQL 变量(在 SQL 中称为别名)可以绑定到 查询计算期间的不同类型。这与 SQL 不同,其中 变量始终绑定到元组。它甚至与什么不同 发生在用例中:取消嵌套标量数组和 在用例:取消嵌套数组数组中发生了什么。

在第一个用例中,PartiQL 变量碰巧总是绑定到一个字符串(给定 示例)。在第二个用例中,PartiQL 变量是 始终绑定到数组(同样,给定 示例)。p``y

要说明绑定到不同类型的变量,请考虑 数据集中的以下扭曲。一些 数组的元素是纯字符串,有些是 元组。即使是员工元组也并不总是具有相同的属性。employeesNest``projects


{ 
    'hr': { 
        'employeesMixed2': <<
            { 
                'id': 3, 
                'name': 'Bob Smith', 
                'title': null, 
                'projects': [ 
                    { 'name': 'AWS Redshift Spectrum querying' },
                    'AWS Redshift security',
                    { 'name': 'AWS Aurora security' }
                ]
            },
            { 
                'id': 4, 
                'name': 'Susan Smith', 
                'title': 'Dev Mgr', 
                'projects': []
            },
            { 
                'id': 6, 
                'name': 'Jane Smith', 
                'projects': [ 'AWS Redshift security'] 
            }
        >>
    }
}  

此查询生成员工姓名 -- 员工 项目对。hr.employeesMixed2


SELECT e.name AS employeeName,
       CASE WHEN (p IS TUPLE) THEN p.name 
       ELSE p END AS projectName
FROM hr.employeesMixed2 AS e,
     e.projects AS p  

请注意子表达式 。可以使用运算符 以在评估时根据其类型检查值。 另请注意,变量绑定到不同的类型。(p IS TUPLE)``IS``p

通常,查询的子句绑定其变量(别名) 到数据。变量不需要绑定到具有相同数据 类型。每个绑定都馈送到子句,子句评估其 表达 式。FROM``SELECT

此表显示了子句生成的每个变量的绑定 以及子句的相应元组输出。FROM``SELECT


+-----------------------+-----------------------+-----------------------+
| Variable `e`          | Variable `p`          | Result tuple          |
+=======================+=======================+=======================+
| { 'id': 3,            | { 'name': 'AWS        | {                     |
|                       | Redshift Spectrum     |                       |
| 'name': 'Bob Smith',  | querying' }           | 'employeeName': 'Bob  |
|                       |                       | Smith',               |
| 'title': null,        |                       |                       |
|                       |                       | 'projectName': 'AWS   |
| 'projects':  [ {      |                       | Redshift Spectrum     |
| 'name': 'AWS Redshift |                       | querying'             |
| Spectrum querying' }, |                       |                       |
|                       |                       | }                     |
| 'AWS Redshift         |                       |                       |
| security',            |                       |                       |
|                       |                       |                       |
| { 'name': 'AWS Aurora |                       |                       |
| security' }           |                       |                       |
|                       |                       |                       |
|  ]                    |                       |                       |
|                       |                       |                       |
| }                     |                       |                       |
+-----------------------+-----------------------+-----------------------+
| { 'id': 3,            | 'AWS Redshift         | {                     |
|                       | security'             |                       |
| 'name': 'Bob Smith',  |                       | 'employeeName': 'Bob  |
|                       |                       | Smith',               |
| 'title': null,        |                       |                       |
|                       |                       | 'projectName': 'AWS   |
| 'projects':  [ {      |                       | Redshift security'    |
| 'name': 'AWS Redshift |                       |                       |
| Spectrum querying' }, |                       | }                     |
|                       |                       |                       |
| 'AWS Redshift         |                       |                       |
| security',            |                       |                       |
|                       |                       |                       |
| { 'name': 'AWS Aurora |                       |                       |
| security' }           |                       |                       |
|                       |                       |                       |
|  ]                    |                       |                       |
|                       |                       |                       |
| }                     |                       |                       |
+-----------------------+-----------------------+-----------------------+
| { 'id': 3,            | { 'name': 'AWS Aurora | {                     |
|                       | security' }           |                       |
| 'name': 'Bob Smith',  |                       | 'employeeName': 'Bob  |
|                       |                       | Smith',               |
| 'title': null,        |                       |                       |
|                       |                       | 'projectName': 'AWS   |
| 'projects': \[ {      |                       | Aurora security'      |
| 'name': 'AWS Redshift |                       |                       |
| Spectrum querying' }, |                       | }                     |
|                       |                       |                       |
| 'AWS Redshift         |                       |                       |
| security',            |                       |                       |
|                       |                       |                       |
| { 'name': 'AWS Aurora |                       |                       |
| security' }           |                       |                       |
|                       |                       |                       |
| \]                    |                       |                       |
|                       |                       |                       |
| }                     |                       |                       |
+-----------------------+-----------------------+-----------------------+
| { 'id': 6,            |   'AWS Redshift       | {                     |
|                       | security'             |                       |
| 'name': 'Jane Smith', |                       |   'employeeName':     |
|                       |                       | 'Jane Smith',         |
| 'projects': \[ 'AWS   |                       |                       |
| Redshift security' \] |                       |   'projectName': 'AWS |
|                       |                       | Redshift security'    |
| }                     |                       |                       |
|                       |                       | }                     |
+-----------------------+-----------------------+-----------------------+  

按顺序访问数组元素

SQL 允许我们使用子句对查询的输出进行排序。但是,SQL 数据模型无法识别 输入数据。相比之下,许多新的数据格式具有数组; 数组的元素有一个顺序。我们可能想找到一个数组元素 通过其索引或,我们可能想要找到某些位置 元素在其数组中。ORDER BY

<Array> [<number>]

让我们再次考虑数据集。hr.employeesNest


{ 
  'hr': { 
      'employeesNest': <<
         { 
          'id': 3, 
          'name': 'Bob Smith', 
          'title': null, 
          'projects': [ { 'name': 'AWS Redshift Spectrum querying' },
                        { 'name': 'AWS Redshift security' },
                        { 'name': 'AWS Aurora security' }
                      ]
          },
          { 
              'id': 4, 
              'name': 'Susan Smith', 
              'title': 'Dev Mgr', 
              'projects': [] 
          },
          { 
              'id': 6, 
              'name': 'Jane Smith', 
              'title': 'Software Eng 2', 
              'projects': [ { 'name': 'AWS Redshift security' } ] 
          }
      >>
    }
}  

该属性是一个元组数组;也就是说,每个元组 有一个与之关联的序数。以下查询返回每个 员工姓名,以及员工的第一个项目。projects


SELECT e.name AS employeeName, 
       e.projects[0].name AS firstProjectName
FROM hr.employeesNest AS e  

查询返回


<<
  {
    'employeeName': 'Bob Smith',
    'firstProjectName': 'AWS Redshift Spectrum querying'
  },
  {
    'employeeName': 'Susan Smith'
  },
  {
    'employeeName': 'Jane Smith',
    'firstProjectName': 'AWS Redshift security'
  }
>>
--- 
OK!  

多步骤路径

从技术上讲,该结构是一种路径步骤。 例如,请注意 4 步路径 。当绑定到 的第一个元组时,路径将结果变为数组[<number>]``e.projects[0].name``e``hr.employeesNest``e.projects


[ 
    { 'name': 'AWS Redshift Spectrum querying' },
    { 'name': 'AWS Redshift security' },
    { 'name': 'AWS Aurora security' }
]  

因此,应用步骤(即 评估 ) 导致 。最后,评估步骤(即评估)线索 自。[0]``e.projects``e.projects[0]``{'name': 'AWS Redshift Spectrum querying'}``.name``e.projects[0]``e.projects[0].name``'AWS Redshift Spectrum querying'

查找数组中每个元素的索引

假设每个员工的项目都按优先级顺序排序。 以下查询查找每个员工的姓名 涉及安全项目、安全项目及其索引 数组。projects


SELECT e.name AS employeeName, 
       p.name AS projectName, 
       o AS projectPriority
FROM hr.employeesNest AS e, 
     e.projects AS p AT o
WHERE p.name LIKE '%security%'  

请注意新功能:。虽然范围超过元素 的数组中,变量被赋给索引 数组中的元素。查询返回:AT o``p``e.projects``o


<<
  {
    'employeeName': 'Bob Smith',
    'projectName': 'AWS Redshift security',
    'projectPriority': 1
  },
  {
    'employeeName': 'Bob Smith',
    'projectName': 'AWS Aurora security',
    'projectPriority': 2
  },
  {
    'employeeName': 'Jane Smith',
    'projectName': 'AWS Redshift security',
    'projectPriority': 0
  }
>>
--- 
OK!  

旋转和取消旋转

许多查询需要范围并收集属性名称/值 元组对或映射的键/值对。

取消枢轴元组

考虑这个数据集,它提供了多个收盘价 股票代码。


{ 
    'closingPrices': <<
        { 'date': '4/1/2019', 'amzn': 1900, 'goog': 1120, 'fb': 180 },
        { 'date': '4/2/2019', 'amzn': 1902, 'goog': 1119, 'fb': 183 }
    >>
}   

以下查询对股票代码/价格对进行反转。


SELECT c."date" AS "date", 
       sym AS "symbol", 
       price AS price
FROM closingPrices AS c, 
     UNPIVOT c AS price AT sym
WHERE NOT sym = 'date'  

请注意在此查询中使用 。双引号允许我们 消除关键字和标识符的歧义。 双引号还可以指定属性查找区分大小写。"``date``"date"

查询返回


<<
  {
    'date': '4/1/2019',
    'symbol': 'amzn',
    'price': 1900
  },
  {
    'date': '4/1/2019',
    'symbol': 'goog',
    'price': 1120
  },
  {
    'date': '4/1/2019',
    'symbol': 'fb',
    'price': 180
  },
  {
    'date': '4/2/2019',
    'symbol': 'amzn',
    'price': 1902
  },
  {
    'date': '4/2/2019',
    'symbol': 'goog',
    'price': 1119
  },
  {
    'date': '4/2/2019',
    'symbol': 'fb',
    'price': 183
  }
>>
--- 
OK!  

取消透视元组允许使用属性名称,就好像它们是 数据。例如,计算每个的平均价格变得容易 符号为


SELECT sym AS "symbol", 
       AVG(price) AS avgPrice
FROM closingPrices c, 
     UNPIVOT c AS price AT sym
WHERE NOT sym = 'date'
GROUP BY sym  

返回


<<
  {
    'symbol': 'amzn',
    'avgPrice': 1901
  },
  {
    'symbol': 'fb',
    'avgPrice': 181.5
  },
  {
    'symbol': 'goog',
    'avgPrice': 1119.5
  }
>>
--- 
OK!  

旋转到元组

旋转将集合转换为元组。例如,考虑 收集


{ 
    'todaysStockPrices': <<
        { 'symbol': 'amzn', 'price': 1900},
        { 'symbol': 'goog', 'price': 1120},
        { 'symbol': 'fb', 'price': 180 }
    >>
}   

然后进行以下查询PIVOT


PIVOT sp.price AT sp."symbol"
FROM todaysStockPrices sp  

生成元组


{
  'amzn': 1900,
  'goog': 1120,
  'fb': 180
}
--- 
OK!  

请注意,该查询看起来像一个查询,只是它有一个 .另请注意,查询不会返回元组集合:而是 它从字面上返回一个元组值。PIVOT``SELECT-FROM-WHERE-...``SELECT``PIVOT <value expression> AT <attribute expression>``PIVOT

用例:旋转子查询

(此示例还使用了 PartiQL 的分组功能,创建 嵌套结果与分组依据...组为。

让我们概括一下前面的枢轴情况。我们有一个表格 股价


{ 
    'stockPrices':<<
        { 'date': '4/1/2019', 'symbol': 'amzn', 'price': 1900},
        { 'date': '4/1/2019', 'symbol': 'goog', 'price': 1120},
        { 'date': '4/1/2019', 'symbol': 'fb',   'price': 180 },
        { 'date': '4/2/2019', 'symbol': 'amzn', 'price': 1902},
        { 'date': '4/2/2019', 'symbol': 'goog', 'price': 1119},
        { 'date': '4/2/2019', 'symbol': 'fb',   'price': 183 }
    >>
}   

我们希望将其透视为元组集合,其中每个元组 具有日期的所有对,如下所示symbol:price


<<
{ 
    'date': date(4/1/2019), 
    'prices': {'amzn': 1900, 'goog': 1120, 'fb': 180} 
},
{ 
    'date': date(4/2/2019), 
    'prices': {'amzn': 1902, 'goog': 1119, 'fb': 183} 
}
>>  

以下查询首先为每个日期创建一个组日期价格。 然后,子查询将组枢轴为元组价格。PIVOT


SELECT sp."date" AS "date", 
       (PIVOT dp.sp.price AT dp.sp."symbol" 
        FROM datesPrices as dp ) AS prices
FROM StockPrices AS sp GROUP BY sp."date" GROUP AS datesPrices  

例如,从 for 返回的集合是datesPrices``GROUP AS``sp.date = date(4/1/2019)


    'datesPrices': <<
      {
        'sp': {
          'date': '4/1/2019',
          'symbol': 'amzn',
          'price': 1900
        }
      },
      {
        'sp': {
          'date': '4/1/2019',
          'symbol': 'goog',
          'price': 1120
        }
      },
      {
        'sp': {
          'date': '4/1/2019',
          'symbol': 'fb',
          'price': 180
        }
      }
    >>  

创建嵌套和非 SQL 结果

PartiQL 允许创建嵌套结果的查询以及查询 产生异构结果。

使用查询创建嵌套结果SELECT VALUE

让我们再次考虑数据集:hr.employeesNestScalars


{ 
    'hr': { 
        'employeesNestScalars': <<
            { 
                'id': 3, 
                'name': 'Bob Smith', 
                'title': null, 
                'projects': [ 
                    'AWS Redshift Spectrum querying',
                    'AWS Redshift security',
                    'AWS Aurora security'
                ]
            },
            { 
                'id': 4, 
                'name': 'Susan Smith', 
                'title': 'Dev Mgr', 
                'projects': []
            },
            { 
                'id': 6, 
                'name': 'Jane Smith', 
                'title': 'Software Eng 2', 
                'projects': [ 'AWS Redshift security' ]
            }
        >>
    } 
}  

以下查询输出 的每个元组, 除了每个元组而不是所有项目只有安全性 员工的项目。这里重要的新功能是 .hr.employeesNestScalars``SELECT VALUE <expression>


SELECT e.id AS id, 
       e.name AS name, 
       e.title AS title,
       ( SELECT VALUE p
         FROM e.projects AS p
         WHERE p LIKE '%security%'
       ) AS securityProjects
FROM hr.employeesNestScalars AS e  

结果是


<<
  {
    'id': 3,
    'name': 'Bob Smith',
    'title': NULL,
    'securityProjects': <<
      'AWS Redshift security',
      'AWS Aurora security'
    >>
  },
  {
    'id': 4,
    'name': 'Susan Smith',
    'title': 'Dev Mgr',
    'securityProjects': <<>>
  },
  {
    'id': 6,
    'name': 'Jane Smith',
    'title': 'Software Eng 2',
    'securityProjects': <<
      'AWS Redshift security'
    >>
  }
>>
--- 
OK!  

查询(或子查询,如 示例) 返回计算结果的集合。SELECT VALUE <expression>``<expression>

注意与SQL的区别,它总是产生 元组。如果 SQL 显示为子查询,则 子查询指定是否应强制子查询的结果 进入标量(例如,当 ),强制进入 标量的集合(例如,何时)等。都不是 这适用于 ,它生成一个集合,并且 收集不是强制的。SELECT``SELECT``5 = <subquery>``5 IN <subquery>``SELECT VALUE

创建嵌套结果GROUP BY ... GROUP AS

在 PartiQL 中创建嵌套结果的另一种模式是通过 SQL 的扩展。这种模式更有效,并且 比使用嵌套查询更直观时 所需的嵌套不遵循输入的嵌套。(示例 在 使用 SELECT VALUE 查询创建嵌套结果 是其中之一 输出中的嵌套遵循输入的嵌套,因此, 直观的解决方案不涉及。GROUP AS``GROUP BY``SELECT VALUE``GROUP BY

以下查询输出在中找到的每个安全项目以及员工姓名列表 在项目上工作。hr.employeesNestScalars


SELECT p AS projectName,
       ( SELECT VALUE v.e.name 
         FROM perProjectGroup AS v ) AS employees
FROM hr.employeesNestScalars AS e JOIN e.projects AS p ON p LIKE '%security%'
GROUP BY p GROUP AS perProjectGroup  

结果是


<<
  {
    'projectName': 'AWS Aurora security',
    'employees': <<
      'Bob Smith'
    >>
  },
  {
    'projectName': 'AWS Redshift security',
    'employees': <<
      'Bob Smith',
      'Jane Smith'
    >>
  }
>>
--- 
OK!  

通过使公式化的 SQL 泛化 对查询的 和 子句完全可用的组。与 SQL 的相反,其中 and 子句可以具有聚合函数 分组列,但它们无法访问 分组列。GROUP AS``GROUP BY``SELECT``HAVING``GROUP BY``SELECT``HAVING

为了更好地理解它的工作原理是 最好将 PartiQL 查询视为子句管道,从 的 ,继续 和 结束。每个子句都是一个输入数据和输出数据的函数。 从这个意义上说,这是一个输入的函数 的结果 和 将其结果输出到 .GROUP BY ... GROUP AS``FROM``GROUP BY``SELECT``GROUP BY ... GROUP AS``FROM``SELECT

以下查询(概念上)生成子句的输出。FROM


SELECT e AS e, p AS p
FROM hr.employeesNestScalars AS e JOIN e.projects AS p ON p LIKE '%security%'  

我们看到,交付的元组集合包括 由该子句输出的员工和项目,即 .这就像SQL的语义。FROM``e``p``FROM``LEFT JOIN``FROM


+-----------------------------------+-----------------------------------+
| Variable `e`                      | Variable `p`                      |
+===================================+===================================+
| { 'id': 3,                        |   'AWS Redshift security'         |
| 'name': 'Bob Smith',              |                                   |
| 'title': null,                    |                                   |
| 'projects':  [ 'AWS Redshift      |                                   |
| Spectrum querying',               |                                   |
| 'AWS Redshift security',          |                                   |
| 'AWS Aurora security'             |                                   |
|  ]                                |                                   |
| }                                 |                                   |
+-----------------------------------+-----------------------------------+
| { 'id': 3,                        |   'AWS Aurora security'           |
| 'name': 'Bob Smith',              |                                   |
| 'title': null,                    |                                   |
| 'projects':  [ 'AWS Redshift      |                                   |
| Spectrum querying',               |                                   |
| 'AWS Redshift security',          |                                   |
| 'AWS Aurora security'             |                                   |
|  ]                                |                                   |
| }                                 |                                   |
+-----------------------------------+-----------------------------------+
| { 'id': 6,                        | 'AWS Redshift security'           |
| 'name': 'Jane Smith',             |                                   |
| 'title': 'Software Eng 2',        |                                   |
| 'projects':  [ 'AWS Redshift      |                                   |
| security'  ]                      |                                   |
| }                                 |                                   |
+-----------------------------------+-----------------------------------+  

那么可以认为输出 每个分组依据表达式都有一列的表(即,每个 安全项目 ) 和最后一列 值(概念上)是对应于分组依据表达式的员工/项目/元组的集合。因此输出是表GROUP BY ... GROUP AS ...``p``perProjectGroup``e``p``p``GROUP BY ... GROUP AS ...


+-----------------------------------+-----------------------------------+
| `p`                               | `perProjectGroup`                 |
+===================================+===================================+
| 'AWS Redshift security'           | <<                              |
|                                   | { e: { 'id': 3, 'name': 'Bob      |
|                                   | Smith', ... }, p: 'AWS Redshift   |
|                                   | security' },                      |
|                                   |                                   |
|                                   | { e: { 'id': 6, 'name': 'Jane     |
|                                   | Smith', ... }, p: 'AWS Redshift   |
|                                   | security' }                       |
|                                   | >>                              |
+-----------------------------------+-----------------------------------+
| 'AWS Aurora security'             | <<                              |
|                                   | { e: { 'id': 3, 'name': 'Bob      |
|                                   | Smith', ...}, p: 'AWS Aurora      |
|                                   | security' },                      |
|                                   | >>                              |
+-----------------------------------+-----------------------------------+  

最后子句输入上述内容并输出查询 结果。SELECT

了解有关 PartiQL 的更多信息

PartiQL 网站包含新闻、更新、 文档,以及有关 PartiQL 实现的更多信息。

转自:

Tutorial · partiql/partiql-lang-kotlin Wiki (github.com)https://github.com/partiql/partiql-lang-kotlin/wiki/Tutorial

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PartiQL 对 SQL 的扩展,可以查询非结构化的数据 的相关文章

随机推荐