You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
MalloySQL enables mixing dialect-specific SQL (including DDL) with Malloy. For example, MalloySQL can be used to create a new table in BigQuery, based on a model of existing data:
4
5
5
-
```malloy
6
-
>>>malloy
7
-
import "airports.malloy"
6
+
```malloy
7
+
>>>malloy
8
+
import "airports.malloy"
8
9
9
-
>>>sql connection:bigquery
10
-
CREATE TABLE major_airports AS ( // this is SQL
11
-
SELECT name
12
-
FROM %{
13
-
airports -> major_airports // this is a Malloy query
14
-
}%
15
-
);
16
-
```
10
+
>>>sql connection:bigquery
11
+
CREATE TABLE major_airports AS ( // this is SQL
12
+
SELECT name
13
+
FROM %{
14
+
airports -> major_airports // this is a Malloy query
15
+
}%
16
+
);
17
+
```
17
18
18
19
## Usage
19
20
20
21
MalloySQL can be used in the VSCode Extension and the Malloy CLI. In both cases, the extension of the file should be `.malloysql`.
21
22
22
23
MalloySQL files are composed of two kinds of statements - Malloy statements and SQL statements. Each statement is preceeded by a line that defines the statement type: `>>>malloy` or `>>>sql`. The SQL statement can also be passed a connection name - this is the name of the connection to use when executing the query. This is valid MalloySQL:
23
24
24
-
```malloy
25
-
>>>sql connection:duckdb
26
-
SELECT 1;
27
-
```
25
+
```malloy
26
+
>>>sql connection:duckdb
27
+
SELECT 1;
28
+
```
28
29
29
30
SQL statements can also contain embedded Malloy queries by wrapping the Malloy statement with `%{` and `}%`. To use embedded Malloy, a source must first be imported to use with the Malloy query:
30
31
31
-
```malloy
32
-
>>>malloy
33
-
import "mysource.malloy"
32
+
```malloy
33
+
>>>malloy
34
+
import "mysource.malloy"
34
35
35
-
>>>sql connection:duckdb
36
-
SELECT name_count from %{ mysource -> names }%;
37
-
```
36
+
>>>sql connection:duckdb
37
+
SELECT name_count from %{ mysource -> names }%;
38
+
```
38
39
39
40
It is possible to use multiple SQL commands in one statement (although only the final result will be shown in the VSCode extension):
40
41
41
-
```malloy
42
-
>>>malloy
43
-
import "mysource.malloy"
42
+
```malloy
43
+
>>>malloy
44
+
import "mysource.malloy"
44
45
45
-
>>>sql connection:duckdb
46
-
SELECT name_count from %{ mysource -> names }%;
47
-
SELECT airport_count from %{ mysource -> airports }%;
48
-
```
46
+
>>>sql connection:duckdb
47
+
SELECT name_count from %{ mysource -> names }%;
48
+
SELECT airport_count from %{ mysource -> airports }%;
49
+
```
49
50
50
51
The first SQL statement must define a connection to be used for queries, but future SQL statements only need to define a connection if a different connection should be used. This is valid:
51
52
52
-
```malloy
53
-
>>>malloy
54
-
import "mysource.malloy"
53
+
```malloy
54
+
>>>malloy
55
+
import "mysource.malloy"
55
56
56
-
>>>sql connection:duckdb
57
-
SELECT name_count from %{ mysource -> names }%;
58
-
>>>sql
59
-
SELECT airport_count from %{ mysource -> airports }%;
60
-
```
57
+
>>>sql connection:duckdb
58
+
SELECT name_count from %{ mysource -> names }%;
59
+
>>>sql
60
+
SELECT airport_count from %{ mysource -> airports }%;
61
+
```
61
62
62
63
It is also possible to define connections in SQL using `--connection:{my_connection}`. This is useful when writing `.malloynb` files, as notebooks cannot obtain data from delimiter lines.
63
64
@@ -69,28 +70,28 @@ Running a specific SQL statement in a Malloy file (by, for example, clicking the
69
70
70
71
Here is a more realistic example, using a Malloy model to wrangle raw data and create a useful parquet file with DuckDB:
71
72
72
-
```malloy
73
-
>>>malloy
74
-
import "raw_data.malloy"
75
-
76
-
>>>sql connection:duckdb
77
-
78
-
copy %{
79
-
raw_titles -> {
80
-
join_one: raw_ratings on tconst = raw_ratings.tconst
81
-
join_one: raw_crew on tconst = raw_crew.tconst
82
-
where: raw_ratings.numVotes > 30000
83
-
project:
84
-
tconst
85
-
isAdult, originalTitle, primaryTitle
86
-
startYear is startYear:::number
87
-
endYear is endYear:::number
88
-
runtimeMinutes is runtimeMinutes:::number
89
-
genres is str_split!(genres,',')
90
-
directors is str_split!(raw_crew.directors,',')
91
-
writers is str_split!(raw_crew.writers,',')
92
-
averageRating is raw_ratings.averageRating:::number
93
-
numVotes is raw_ratings.numVotes:::number
94
-
}
95
-
}% to 'data/titles.parquet' (FORMAT 'parquet', CODEC 'ZSTD')
96
-
```
73
+
```malloy
74
+
>>>malloy
75
+
import "raw_data.malloy"
76
+
77
+
>>>sql connection:duckdb
78
+
79
+
copy %{
80
+
raw_titles -> {
81
+
join_one: raw_ratings on tconst = raw_ratings.tconst
82
+
join_one: raw_crew on tconst = raw_crew.tconst
83
+
where: raw_ratings.numVotes > 30000
84
+
project:
85
+
tconst
86
+
isAdult, originalTitle, primaryTitle
87
+
startYear is startYear:::number
88
+
endYear is endYear:::number
89
+
runtimeMinutes is runtimeMinutes:::number
90
+
genres is str_split!(genres,',')
91
+
directors is str_split!(raw_crew.directors,',')
92
+
writers is str_split!(raw_crew.writers,',')
93
+
averageRating is raw_ratings.averageRating:::number
94
+
numVotes is raw_ratings.numVotes:::number
95
+
}
96
+
}% to 'data/titles.parquet' (FORMAT 'parquet', CODEC 'ZSTD')
0 commit comments