This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-03-15
Channels
- # babashka (4)
- # beginners (136)
- # calva (63)
- # clerk (7)
- # clj-kondo (8)
- # clojure (43)
- # clojure-boston (1)
- # clojure-europe (37)
- # clojure-nl (1)
- # clojure-norway (11)
- # clojure-uk (3)
- # clojurescript (6)
- # clr (1)
- # code-reviews (16)
- # cursive (45)
- # datomic (2)
- # docker (32)
- # emacs (10)
- # events (2)
- # exercism (1)
- # fulcro (3)
- # hugsql (1)
- # hyperfiddle (47)
- # leiningen (3)
- # lsp (30)
- # malli (39)
- # missionary (1)
- # off-topic (24)
- # pathom (2)
- # portal (14)
- # practicalli (5)
- # rdf (13)
- # reagent (18)
- # reitit (18)
- # releases (7)
- # remote-jobs (1)
- # sci (2)
- # shadow-cljs (45)
- # sql (7)
- # tools-build (11)
- # xtdb (13)
Need a little brain help here. So imagine I have to tables foo
and bar
and I executed a query like
select f.*, b.* from foo f, bar b where f.col = b.other_col
Putting this through straight next.jdbc
I get a bunch of rows on a form of:
[{:foo/id
:foo/name
:foo/col
:bar/id
:bar/name
:bar/other_col}
...]
What I would like to have is something like:
{:foo [{id, name, col} {id, name, col} ...]
:bar [{id, name, other_col}, {id, name, other_col} ...]}
ie I would love for the result to be grouped by table.
Is this possible with a mix of sql and next.jdbc trickery?Here is how I'd do what you are asking in SQL Server:
select
(select t.*
from sys.tables t
where exists (
select 1 from sys.columns c
where c.object_id = t.object_id
) for json path, without_array_wrapper) as [tables],
(select c.*
from sys.columns c
where c.object_id in (
select object_id from sys.tables
) for json path) as [columns]
for json path, without_array_wrapper
Though for me I'd rather have a tree than 2 flat lists, so I'd do it this way, but depends on use case I guess:
select
(select t.* for json path, without_array_wrapper) as [table],
(select c.* from sys.columns c where c.object_id = t.object_id for json path) as [columns]
from sys.tables t
for json path
This is SQL server, but it is also possible in postgres, I just don't have the syntax.I’m at:
(defn group-row [row]
(->> row
(group-by (comp keyword namespace first))
(medley/map-vals #(into {} %))
(medley/map-vals #(medley/map-keys (comp keyword name) %))))
(defn group-result [r]
(->> r
(map group-row)
(apply merge-with (fn [e1 e2]
(if (set? e1)
(conj e1 e2)
(set (vector e1 e2)))))))
which I can apply to a result from next.jdbc. I’m sure this can be rewritten to some sort of builder fn.Fair enough. I've avoided that type of logic, because it breaks down if cardinalities change, or you refer to the same table more than once in different contexts, etc.
Seems like playing around with https://github.com/seancorfield/next-jdbc/blob/develop/doc/result-set-builders.md would do the trick…
This is a ticket where I've been thinking about those sorts of coalescing and transforming operations https://github.com/seancorfield/next-jdbc/issues/201 @slipset -- feel free to add ideas there and maybe sketches of code?