Remix.run Logo
snthpy 8 months ago

Hi,

Having this sort of "table polymorphism" is something we've thought a lot about for PRQL and is definitely something we want to get right. That said it's not straightforward but you can do a lot of it already. You can try the following examples for yourself in the PRQL Playground (https://prql-lang.org/playground/).

First a simple example using functions as they are documented:

```prql

let fullname = func firstname lastname -> f"{firstname} {lastname}"

from customers

select full_name=(fullname first_name last_name)

```

Now the example above isn't quite what you're looking for because you still have to specify the columns as function arguments and there really isn't much gained here. It serves to illustrate the principle though as the `fullname` function could be doing something more complicated.

What you want is:

```prql

let add_full_name = func tbl<relation> -> (

    from tbl

    derive full_name = f"{first_name} {last_name}"

    )
from customers

add_full_name

select full_name

```

Now this requires the `<relation>` type annotation which hasn't been documented because it's still quite experimental. However this works right now and can be applied to different tables or relations, for example you could use the same function in the following:

```prql

from i=invoices

join c=customers (==customer_id)

select {c.first_name, c.last_name, i.total}

sort {-total}

add_full_name

select {full_name, total}

```

I'll add some more examples in child comments.

Disclaimer: I'm a PRQL contributor.