Hello everyone 👋 How do I translate this query into honeysql ?
SELECT name
FROM dinosaurs
ORDER BY random() --- please help with this line ---
LIMIT 10;
specifically, the order by random() part ?
I'm using honeysql 2.7.1350 and the database is PostgreSQL
(defn plz-halp-ty!
"Get a random sample from the db"
[]
{:select [:name]
:from :dinosaurs
:order-by [:raw "RANDOM()"] ;; i've tried a gazillion stuff and I'm stuck here
:limit 10})
(honey.sql/format {:select [:name]
:from :dinosaurs
:order-by [[[:random]]]
:limit 10})
=> ["SELECT name FROM dinosaurs ORDER BY RANDOM() ASC LIMIT ?" 10]thank you thank you thank you! 🕺 🙌 👏
how did you know triple [[[ would do the trick ? @p-himik
In general, the top level [] means a collection of things, the next level of [] means aliases (like for :select, :from, etc.) or extra parameters (like for :order-by, where you can specify :desc that way, for example), and the third level of [] means function calling.
BTW :select [:name] can be written as :select :name.
thank you very much, you've made my day bowtie
No problem. :)
The docs have this example for ORDER BY but I can see how it wouldn't be obvious to extrapolate to the case you wanted:
user=> (sql/format '{select (*) from table
;; explicit direction provided:
order-by ((status asc), ((year created-date) asc))})
["SELECT * FROM table ORDER BY status ASC, YEAR(created_date) ASC"]I'm adding these two additional examples:
user=> (sql/format {:select [:*] :from :table
;; explicit direction provided:
:order-by [[:status :asc] [[:year :created-date] :asc]]})
["SELECT * FROM table ORDER BY status ASC, YEAR(created_date) ASC"]
user=> (sql/format {:select [:*] :from :table
;; order by single function:
:order-by [[[:random]]]})
["SELECT * FROM table ORDER BY RANDOM() ASC"]Just curious - why does :with require pairing of its arguments? Unlike e.g. :from or :join.
There's also a somewhat relevant ancient issue describing the confusion: https://github.com/seancorfield/honeysql/issues/164
I suspect the logic was "Well, it's a bit like an alias -- WITH expr AS ident -- and SELECT uses pairs for aliases, and a sequence of pairs for multiple expressions/aliases, so WITH should "match" that, even tho' the "alias" comes before the expression...?
{select ((foo.bar old) (quux.bar new)) ...} and {with ((old foo.bar) (new quux.bar)) ...}
But I'd probably have to go back in time to when it was first added and see if there are any bread crumbs...
Ah, I see.
In my mind, :with is closer to Clojure's let, which can be contrasted with some other lisps here, because there are no extra () around each pair. :)
Yeah, there could be an argument for supporting just an alternating sequence of ident/expr and partitioning I guess...
Eh, I wouldn't touch it, I think. It's documented. Way too many little things to tackle each and every one. :)