Re: DISTINCT *and* ORDER BY in aggregate functions on expressions(!)y - Mailing list pgsql-general

From Thorsten Glaser
Subject Re: DISTINCT *and* ORDER BY in aggregate functions on expressions(!)y
Date
Msg-id 9fc8e12b-f943-c633-a37-254915f819a0@evolvis.org
Whole thread Raw
In response to Re: DISTINCT *and* ORDER BY in aggregate functions on expressions(!)  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: DISTINCT *and* ORDER BY in aggregate functions on expressions(!)y
List pgsql-general
On Mon, 27 Feb 2023, David G. Johnston wrote:

>Consider this then as a jumping point to a more precise query form:
[…]
>the basic concept holds - produce single rows in subqueries then join those
>various single rows together to produce your desired json output.

Ouch. I’ll have to read up and experiment with that, I guess.
But wouldn’t I rather then do a CTA for each referenced table
that does the aggregating and GROUP BY person_id, then join that
(which has single rows for each user row) to users?

>--BAD cross joining going on with multiple one-to-many relationships
>--GOOD, only joining one-to-one relationships

Not quite. This is many-to-many created by Django…


On Mon, 27 Feb 2023, Tom Lane wrote:

>Sure, I was just trying to explain the rule.

Aaah, okay. Sorry, I misunderstood that, and the… general direction
of the replies, then.

>Well, that may be what you want, but it's not what you wrote in
>the query.  Follow David's advice and do
[…]
>I'm pretty sure that this will only incur one evaluation of the
>common subexpression, so even though it's tedious to type it's not
>inefficient.

Thanks. But I fear it’s not as simple as you wrote. More like:

jsonb_build_object('opening_times',
    jsonb_agg(DISTINCT jsonb_build_object(
        'weekday', cot.weekday,
        'from_hour', cot.from_hour,
        'to_hour', cot.to_hour)
    ORDER BY
        jsonb_build_object(
        'weekday', cot.weekday,
        'from_hour', cot.from_hour,
        'to_hour', cot.to_hour)->>'weekday',
        jsonb_build_object(
        'weekday', cot.weekday,
        'from_hour', cot.from_hour,
        'to_hour', cot.to_hour)->>'from_hour',
        jsonb_build_object(
        'weekday', cot.weekday,
        'from_hour', cot.from_hour,
        'to_hour', cot.to_hour)->>'to_hour')
)

Isn’t that more like it?

(Though I guess at that point I could just drop at least
the to_hour fallback sort, hoping nobody inserts overlapping
hours with indentical start times…)

Now that I see that, it sort of re-raises a question I had
during developing this but didn’t pursue.

How about, instead of creating a JSONB object here, I create
a (not-JSON) ARRAY['weekday', cot.weekday, 'from_hour',
cot.from_hour, 'to_hour', cot.to_hour] in the aggregate function.
The array is something I could naturally use to sort (its elements
already are in sort key order), and its elements *also* are in
the order jsonb_build_object expects its arguments (assuming I can
do something like passing the array to it instead of “spreading”
the arguments). Pseudocode:

… hmm, not that easy. The aggregate would return e.g. this…

ARRAY[['weekday',1,…],['weekday',2,…]]

… and there’s no array_map function that could be used to pass
each inner array, one by one, to jsonb_build_object; converting
the outer array to JSON gets us json_array_elements (same problem),
other ways I can think of also don’t seem to have matching functions
(jq has… interesting ones).

As I write this, I fear that won’t fly because nōn-JSON arrays
cannot contain mixed types (text and numbers) in PostgreSQL… at
least I ran into that at some point in the past vaguely remembering…

Oh well,
//mirabilos
--
Solange man keine schmutzigen Tricks macht, und ich meine *wirklich*
schmutzige Tricks, wie bei einer doppelt verketteten Liste beide
Pointer XORen und in nur einem Word speichern, funktioniert Boehm ganz
hervorragend.        -- Andreas Bogk über boehm-gc in d.a.s.r



pgsql-general by date:

Previous
From: "David G. Johnston"
Date:
Subject: Re: DISTINCT *and* ORDER BY in aggregate functions on expressions(!)
Next
From: Alban Hertroys
Date:
Subject: Re: DISTINCT *and* ORDER BY in aggregate functions on expressions(!)y