[Special Characters][A] [B] [C] [D] [E] [F] [G] [H] [I] [J] [K] [L] [M] [N] [O] [P] [Q] [R] [S] [T] [U] [V] [W] [X] [Y] [Z]
(let ((param-latitude nil) (param-longitude t)) (query (:select 'id 'name (when param-latitude '0) (when param-longitude 'longitude) :from 'countries :where (:= 'id 20))))((20 "UK" NIL -2))As stated in the postgresql documentation: "When a query involves multiple window functions, it is possible to write out each one with a separate OVER clause, but this is duplicative and error-prone if the same windowing behavior is wanted for several functions. Instead, each windowing behavior can be named in a WINDOW clause and then referenced in OVER". http://www.postgresql.org/docs/9.1/static/tutorial-window.html. They are available in postmodern as of the 29 October 2013 additions to the git repository.
(query (:select (:over (:sum 'salary) 'w) (:over (:avg 'salary) 'w) :from 'empsalary :window (:as 'w (:partition-by 'depname :order-by (:desc 'salary)))))With queries are often referred to as Common Table Expressions. They are used as ways to write auxiliary statements for use in a larger query. The Postgresql documentation covers them at http://www.postgresql.org/docs/9.1/static/queries-with.html.
(query (:with (:as 'upd (:parens (:update 'employees :set 'sales-count (:= 'sales-count 1) :where (:= 'id (:select 'sales-person :from 'accounts :where (:= 'name "Acme Corporation"))) :returning '*))) (:insert-into 'employees-log (:select '* 'current-timestamp :from 'upd))))With-recursive allows the with auxiliary statement to refer to itself. These queries match the following template:
WITH RECURSIVE [temp table] [column list]AS ( [seed statement]UNION ALL [recursive statement - effectively looping through the table] )[outer query which specifies the fields to be kept in the final result and throws away the intermediate results] A few postmodern samples follow which match up with the postgresql documentation examples:
(query (:with-recursive (:as (:t1 'n) (:union-all (:values (:set 1)) (:select (:+ 'n 1) :from 't1 :where (:< 'n 100)))) (:select (:sum 'n) :from 't1)) :single)(query (:with-recursive (:as (:included-parts 'sub-part 'part 'quantity) (:union-all (:select 'sub-part 'part 'quantity :from 'parts :where (:= 'part "our-product")) (:select 'p.sub-part 'p.part 'p.quantity :from (:as 'included-parts 'pr) (:as 'parts 'p) :where (:= 'p.part 'pr.sub-part)))) (:select 'sub-part (:as (:sum 'quantity) 'total-quantity) :from 'included-parts :group-by 'sub-part)))(query (:with-recursive (:as (:search-graph 'id 'link 'data 'depth) (:union-all (:select 'g.id 'g.link 'g.data 1 :from (:as 'graph 'g)) (:select 'g.id 'g.link 'g.data (:= 'sg.depth 1) :from (:as 'graph 'g) (:as 'search-graph 'sg) :where (:= 'g.id 'sg.link)))) (:select '* :from 'search-graph)))(query (:with-recursive (:as (:search-graph 'id 'link 'data'depth 'path 'cycle) (:union-all (:select 'g.id 'g.link 'g.data 1 (:[] 'g.f1 'g.f2) nil :from (:as 'graph 'g)) (:select 'g.id 'g.link 'g.data (:= 'sg.depth 1) (:|| 'path (:row 'g.f1 'g.f2)) (:= (:row 'g.f1 'g.f2) (:any* 'path)) :from (:as 'graph 'g) (:as 'search-graph 'sg) :where (:and (:= 'g.id 'sg.link) (:not 'cycle))))) (:select '* :from 'search-graph)))As a different example, consider a quicklisp dependency table where the fields are 'depends_on' and 'depended_on'. In other words library staple depends-on alexandria. So one record has "staple" in the depends_on column and "alexandria" in the depended_on column.
A function to return a list of all the dependencies of a quicklisp library (assuming the data is in a table called "dependencies") could look like this:
(defun list-dependencies (lib-name) "Returns a list of the names of the direct and indirect libraries depended-on by lib-name." (sort (alexandria:flatten (postmodern:query (:with-recursive (:as 'children (:union (:select 'depended-on :from 'dependencies :where (:= 'depends-on '$1)) (:select 'a.depended-on :from (:as 'dependencies 'a) :inner-join (:as 'children 'b) :on (:= 'a.depends-on 'b.depended-on)))) (:select '* :from 'children)) lib-name)) #'string<))