管道化关系查询语言,发音为“Prequel”
Pipelined Relational Query Language, Pronounced "Prequel"

原始链接: https://prql-lang.org/

PRQL 是一种新的查询语言,旨在为数据操作提供更类似于 Python、更易读的语法,为 SQL 提供了一个引人注目的替代方案。它通过诸如简洁的过滤(`filter plays > 10_000`)、范围表达式(`..`)和简单的日期/间隔字面量等特性来强调清晰度。 主要功能包括:使用表达式派生新列、灵活的分组与分组后过滤、窗口函数(如滚动求和)以及定义可重用函数(`let celsius_to_fahrenheit = ...`)。PRQL 使用 `??` 运算符(类似于 Python 的 `or`)优雅地处理空值。 值得注意的是,PRQL 支持“s-strings”,允许嵌入原生 SQL 以进行复杂操作。它还提供特定方言的目标定位——通过 MSSQL 生成 `TOP` 而不是 `LIMIT` 来演示。该语言支持连接,并为诸如查找每个组的最新记录等常见任务提供了一种简化的方法,这些任务在标准 SQL 中通常很复杂。

## PRQL:一种新的查询语言 一种名为PRQL(Pipelined Relational Query Language,管道关系查询语言)的新查询语言正受到关注,旨在比传统的SQL提供一种更优雅的数据查询方法。Hacker News上的讨论强调了它的潜力,并指出其简洁、重新设计的语法优于谷歌类似的“管道语法”,后者是*构建在*SQL之上的。 然而,讨论也提出了对项目动力的质疑,担心项目“帖子”页面更新不频繁,尽管Git仓库中有近期活动。 一个反复出现的问题集中在“PRQL”这个名称本身,评论者认为它容易被误读——类似于早期对“SQL”(发音为“sequel”,而不是逐字发音)的经历。这场争论涉及软件项目直观命名的重要性。
相关文章

原文

from employees
select {id, first_name, age}
sort age
take 10
SELECT
  id,
  first_name,
  age
FROM
  employees
ORDER BY
  age
LIMIT
  10
from track_plays
filter plays > 10_000                # Readable numbers
filter (length | in 60..240)         # Ranges with `..`
filter recorded > @2008-01-01        # Simple date literals
filter released - recorded < 180days # Nice interval literals
sort {-length}                       # Concise order direction
SELECT
  *
FROM
  track_plays
WHERE
  plays > 10000
  AND length BETWEEN 60 AND 240
  AND recorded > DATE '2008-01-01'
  AND released - recorded < INTERVAL 180 DAY
ORDER BY
  length DESC
from employees
# `filter` before aggregations...
filter start_date > @2021-01-01
group country (
  aggregate {max_salary = max salary}
)
# ...and `filter` after aggregations!
filter max_salary > 100_000
SELECT
  country,
  MAX(salary) AS max_salary
FROM
  employees
WHERE
  start_date > DATE '2021-01-01'
GROUP BY
  country
HAVING
  MAX(salary) > 100000
from track_plays
derive {
  finished = started - unfinished,
  fin_share = finished / started,        # Use previous definitions
  fin_ratio = fin_share / (1-fin_share), # BTW, hanging commas are optional!
}
SELECT
  *,
  started - unfinished AS finished,
  (started - unfinished) / started AS fin_share,
  (started - unfinished) / started / (1 - (started - unfinished) / started)
   AS fin_ratio
FROM
  track_plays
from web
# Just like Python
select url = f"https://www.{domain}.{tld}/{page}"
SELECT
  CONCAT('https://www.', domain, '.', tld, '/', page) AS url
FROM
  web
from employees
group employee_id (
  sort month
  window rolling:12 (
    derive {trail_12_m_comp = sum paycheck}
  )
)
SELECT
  *,
  SUM(paycheck) OVER (
    PARTITION BY employee_id
    ORDER BY
      month ROWS BETWEEN 11 PRECEDING AND CURRENT ROW
  ) AS trail_12_m_comp
FROM
  employees
let celsius_to_fahrenheit = temp -> temp * 9/5 + 32

from weather
select temp_f = (celsius_to_fahrenheit temp_c)
SELECT
  temp_c * 9 / 5 + 32 AS temp_f
FROM
  weather
# Most recent employee in each role
# Quite difficult in SQL...
from employees
group role (
  sort join_date
  take 1
)
WITH table_0 AS (
  SELECT
    *,
    ROW_NUMBER() OVER (
      PARTITION BY role
      ORDER BY
        join_date
    ) AS _expr_0
  FROM
    employees
)
SELECT
  *
FROM
  table_0
WHERE
  _expr_0 <= 1
# There's no `version` in PRQL, but s-strings
# let us embed SQL as an escape hatch:
from x
derive db_version = s"version()"
SELECT
  *,
  version() AS db_version
FROM x
from employees
join b=benefits (==employee_id)
join side:left p=positions (p.id==employees.employee_id)
select {employees.employee_id, p.role, b.vision_coverage}
SELECT
  employees.employee_id,
  p.role,
  b.vision_coverage
FROM
  employees
  INNER JOIN benefits AS b ON employees.employee_id = b.employee_id
  LEFT OUTER JOIN positions AS p ON p.id = employees.employee_id
from users
filter last_login != null
filter deleted_at == null
derive channel = channel ?? "unknown"
SELECT
  *,
  COALESCE(channel, 'unknown') AS channel
FROM
  users
WHERE
  last_login IS NOT NULL
  AND deleted_at IS NULL
prql target:sql.mssql  # Will generate TOP rather than LIMIT

from employees
sort age
take 10
SELECT
  *
FROM
  employees
ORDER BY
  age OFFSET 0 ROWS
FETCH
  FIRST 10 ROWS ONLY
联系我们 contact @ memedata.com