on dev help sign in
Merge branch 'dev' into dev-fun
6817f11Eitan Chatav
squeal-postgresql/src/Squeal/PostgreSQL/Query.hs+44
@@ -39,6 +39,8 @@ module Squeal.PostgreSQL.Query
39 , select_
39 , select_
40 , selectDistinct
40 , selectDistinct
41 , selectDistinct_
41 , selectDistinct_
42+ , selectDistinctOn
43+ , selectDistinctOn_
42 , Selection (..)
44 , Selection (..)
43 -- ** Values
45 -- ** Values
44 , values
46 , values
@@ -573,6 +575,48 @@ selectDistinct_
573 -> Query outer commons schemas params columns
575 -> Query outer commons schemas params columns
574selectDistinct_ = selectDistinct . List
576selectDistinct_ = selectDistinct . List
575
577
578+{-|
579+`selectDistinctOn` keeps only the first row of each set of rows where
580+the given expressions evaluate to equal. The DISTINCT ON expressions are
581+interpreted using the same rules as for ORDER BY. ORDER BY is used to
582+ensure that the desired row appears first.
583+-}
584+selectDistinctOn
585+ :: (SListI columns, columns ~ (col ': cols))
586+ => [SortExpression outer commons 'Ungrouped schemas params from]
587+ -- ^ distinct on and return the first row in ordering
588+ -> Selection outer commons 'Ungrouped schemas params from columns
589+ -- ^ selection
590+ -> TableExpression outer commons 'Ungrouped schemas params from
591+ -- ^ intermediate virtual table
592+ -> Query outer commons schemas params columns
593+selectDistinctOn distincts selection tab = UnsafeQuery $
594+ "SELECT DISTINCT ON"
595+ <+> parenthesized (commaSeparated (renderDistinctOn <$> distincts))
596+ <+> renderSQL selection
597+ <+> renderSQL (tab {orderByClause = distincts <> orderByClause tab})
598+ where
599+ renderDistinctOn = \case
600+ Asc expression -> renderSQL expression
601+ Desc expression -> renderSQL expression
602+ AscNullsFirst expression -> renderSQL expression
603+ DescNullsFirst expression -> renderSQL expression
604+ AscNullsLast expression -> renderSQL expression
605+ DescNullsLast expression -> renderSQL expression
606+
607+-- | Like `selectDistinctOn` but takes an `NP` list of `Expression`s instead
608+-- of a general `Selection`.
609+selectDistinctOn_
610+ :: (SListI columns, columns ~ (col ': cols))
611+ => [SortExpression outer commons 'Ungrouped schemas params from]
612+ -- ^ distinct on and return the first row in ordering
613+ -> NP (Aliased (Expression outer commons 'Ungrouped schemas params from)) columns
614+ -- ^ selection
615+ -> TableExpression outer commons 'Ungrouped schemas params from
616+ -- ^ intermediate virtual table
617+ -> Query outer commons schemas params columns
618+selectDistinctOn_ distincts = selectDistinctOn distincts . List
619+
576-- | `values` computes a row value or set of row values
620-- | `values` computes a row value or set of row values
577-- specified by value expressions. It is most commonly used
621-- specified by value expressions. It is most commonly used
578-- to generate a “constant table” within a larger command,
622-- to generate a “constant table” within a larger command,