diff --git a/README.md b/README.md index adc8d946fc55..4dfa21bff544 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ aggregate { # `aggregate` reduces each column } ``` -Here's a fuller example of the language; +Here's a fuller example of the language: ```elm from employees diff --git a/web/book/src/README.md b/web/book/src/README.md new file mode 100644 index 000000000000..f66579f3b51a --- /dev/null +++ b/web/book/src/README.md @@ -0,0 +1,60 @@ +# PRQL language book + +**P**ipelined **R**elational **Q**uery **L**anguage, pronounced "Prequel". + +PRQL is a modern language for transforming data — a simple, powerful, pipelined +SQL replacement. Like SQL, it's readable, explicit and declarative. Unlike SQL, +it forms a logical pipeline of transformations, and supports abstractions such +as variables and functions. It can be used with any database that uses SQL, +since it compiles to SQL. + +This book serves as a tutorial and reference guide on the language and the +broader project. It currently has three sections, navigated by links on the +left: + +- **Tutorial** — A friendly & accessible guide for learning PRQL. It has a + gradual increase of difficulty and requires only basic understanding of + programming languages. Knowledge of SQL is beneficial, because of many + comparisons to SQL, but not required. +- **Reference** — In-depth information about the PRQL language. Includes + justifications for language design decisions and formal specifications for + parts of the language. +- **Project** — General information about the project, tooling and development. + +--- + +To lead with a couple of examples, with a comparison to SQL: the language can be +as simple as: + +```prql +from tracks +filter artist == "Bob Marley" # Each line transforms the previous result +aggregate { # `aggregate` reduces each column to a value + plays = sum plays, + longest = max length, + shortest = min length, # Trailing commas are allowed +} +``` + +...and here's a fuller example: + +```prql +from employees +filter start_date > @2021-01-01 # Clear date syntax +derive { # `derive` adds columns / variables + gross_salary = salary + (tax ?? 0), # Terse coalesce + gross_cost = gross_salary + benefits_cost, # Variables can use other variables +} +filter gross_cost > 0 +group {title, country} ( # `group` runs a pipeline over each group + aggregate { # `aggregate` reduces each group to a value + average gross_salary, + sum_gross_cost = sum gross_cost, # `=` sets a column name + } +) +filter sum_gross_cost > 100_000 # `filter` replaces both of SQL's `WHERE` & `HAVING` +derive id = f"{title}_{country}" # F-strings like Python +derive country_code = s"LEFT(country, 2)" # S-strings allow using SQL as an escape hatch +sort {sum_gross_cost, -country} # `-country` means descending order +take 1..20 # Range expressions (also valid here as `take 20`) +``` diff --git a/web/book/src/SUMMARY.md b/web/book/src/SUMMARY.md index 5db30a4d0a3c..003b694705e3 100644 --- a/web/book/src/SUMMARY.md +++ b/web/book/src/SUMMARY.md @@ -1,5 +1,9 @@ +# Introduction + +[Introduction](./README.md) + # Tutorial A friendly & accessible guide for learning PRQL. It has a gradual increase of diff --git a/web/book/tests/documentation/snapshots/documentation__book__README__prql-language-book__0.snap b/web/book/tests/documentation/snapshots/documentation__book__README__prql-language-book__0.snap new file mode 100644 index 000000000000..e12ec89ab9f1 --- /dev/null +++ b/web/book/tests/documentation/snapshots/documentation__book__README__prql-language-book__0.snap @@ -0,0 +1,12 @@ +--- +source: web/book/tests/documentation/book.rs +expression: "from tracks\nfilter artist == \"Bob Marley\" # Each line transforms the previous result\naggregate { # `aggregate` reduces each column to a value\n plays = sum plays,\n longest = max length,\n shortest = min length, # Trailing commas are allowed\n}\n" +--- +SELECT + COALESCE(SUM(plays), 0) AS plays, + MAX(length) AS longest, + MIN(length) AS shortest +FROM + tracks +WHERE + artist = 'Bob Marley' diff --git a/web/book/tests/documentation/snapshots/documentation__book__README__prql-language-book__1.snap b/web/book/tests/documentation/snapshots/documentation__book__README__prql-language-book__1.snap new file mode 100644 index 000000000000..8def58104768 --- /dev/null +++ b/web/book/tests/documentation/snapshots/documentation__book__README__prql-language-book__1.snap @@ -0,0 +1,45 @@ +--- +source: web/book/tests/documentation/book.rs +expression: "from employees\nfilter start_date > @2021-01-01 # Clear date syntax\nderive { # `derive` adds columns / variables\n gross_salary = salary + (tax ?? 0), # Terse coalesce\n gross_cost = gross_salary + benefits_cost, # Variables can use other variables\n}\nfilter gross_cost > 0\ngroup {title, country} ( # `group` runs a pipeline over each group\n aggregate { # `aggregate` reduces each group to a value\n average gross_salary,\n sum_gross_cost = sum gross_cost, # `=` sets a column name\n }\n)\nfilter sum_gross_cost > 100_000 # `filter` replaces both of SQL's `WHERE` & `HAVING`\nderive id = f\"{title}_{country}\" # F-strings like Python\nderive country_code = s\"LEFT(country, 2)\" # S-strings allow using SQL as an escape hatch\nsort {sum_gross_cost, -country} # `-country` means descending order\ntake 1..20 # Range expressions (also valid here as `take 20`)\n" +--- +WITH table_1 AS ( + SELECT + title, + country, + salary + COALESCE(tax, 0) + benefits_cost AS _expr_1, + salary + COALESCE(tax, 0) AS _expr_2 + FROM + employees + WHERE + start_date > DATE '2021-01-01' +), +table_0 AS ( + SELECT + title, + country, + AVG(_expr_2) AS _expr_0, + COALESCE(SUM(_expr_1), 0) AS sum_gross_cost + FROM + table_1 + WHERE + _expr_1 > 0 + GROUP BY + title, + country +) +SELECT + title, + country, + _expr_0, + sum_gross_cost, + CONCAT(title, '_', country) AS id, + LEFT(country, 2) AS country_code +FROM + table_0 +WHERE + sum_gross_cost > 100000 +ORDER BY + sum_gross_cost, + country DESC +LIMIT + 20