Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Subqueries section #7

Open
refset opened this issue May 27, 2021 · 0 comments
Open

Subqueries section #7

refset opened this issue May 27, 2021 · 0 comments

Comments

@refset
Copy link
Contributor

refset commented May 27, 2021

Hi all,
I had a question about Q2 from the aggregates section https://nextjournal.com/try/learn-crux-datalog-today/learn-crux-datalog-today#aggregates.
Particularly about adapting the following solution
(q '{:find [(min date)]
     :where [[_ :person/born date]]})
This returns the birthdate of the oldest person in our dataset.
The question is, can the query be adapted to also return the name of this person.
My naive idea was to do something like
(q '{:find [name (min date)]
     :where [[_ :person/born date]
             [_ :person/name name]]})
however this doesn't work because it will return a set of items where each item is the name of a different person.
So how can we couple the name to refer to the data coming from the aggregator. Can we only achieve this with 2 queries? Maybe we can only achieve this by also providing some relational list in the arguments? (edited) 
Nextjournal
Learn Crux Datalog Today
Learn Crux Datalog Today is derived from the classic learndatalogtoday.org tutorial materials, but adapted to focus on the Crux API and unique Datalog semantics, and extended with additional topics and exercises. It is an interactive tutorial designed to teach you the Crux dialect of Datalog. Datalog is a declarative database query language with roots in logic programming. Datalog has similar expressive power to SQL.
2 replies

refset:crux:  4 hours ago
Hi, good question! I think you're right that 2 queries is the answer, but using subqueries you can still treat it as one query:
(q '{:find [name date]
     :where [[(q '{:find [(min date)]
                   :where [[_ :person/born date]]}) [[date]]]
             [p :person/born date]
             [p :person/name name]]})
(note, I've not attempted to actually run this yet...)
That query may still return multiple names though, since multiple persons can share the same birth date, so you might want to also do an :order-by [[name :asc]] and :limit 1 if you are looking for a single deterministic result
For a more complex example of subqueries see here https://github.com/juxt/crux/blob/6d602bb5b6caed199f10fd8c3711cb034d49248a/crux-test/src/crux/fixtures/tpch.clj#L285-L317 
I checked and your solution did work. Thanks!
@refset refset transferred this issue from xtdb-labs/learn-crux-datalog-today Sep 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant