         }
     }
     
+    /// Creates an aggregate which evaluate to the maximum value of the given
+    /// expression in associated records.
+    ///
+    /// When the maximized expression is a column, the aggregate has a default
+    /// name which is "maximum[Key][Column]", where key is the key of the
+    /// association. For example:
+    ///
+    /// For example:
+    ///
+    ///     struct TeamInfo: FetchableRecord, Decodable {
+    ///         var team: Team
+    ///         var maxPlayerScore: Double
+    ///     }
+    ///     let request = Team.annotated(with: Team.players.max(Column("score")))
+    ///     let infos: [TeamInfo] = try TeamInfo.fetchAll(db, request)
+    ///
+    ///     let teams: [Team] = try Team.having(Team.players.max(Column("score")) < 100).fetchAll(db)
+    public func max(_ expression: SQLSpecificExpressible) -> AssociationAggregate<OriginRowDecoder> {
+        let aggregate = makeAggregate(.aggregate("MAX", [expression.sqlExpression]))
+        if let column = expression as? ColumnExpression {
+            let name = key.singularizedName
+            return aggregate.forKey("max\(name.uppercasingFirstCharacter)\(column.name.uppercasingFirstCharacter)")
+        } else {
+            return aggregate
+        }
+    }
+    
     /// Creates an aggregate which evaluate to the minimum value of the given
     /// expression in associated records.
     ///

    ///     let infos: [TeamInfo] = try TeamInfo.fetchAll(db, request)
    ///
    ///     let teams: [Team] = try Team.having(Team.players.sum(Column("score")) > 100).fetchAll(db)
    public func sum(_ expression: SQLExpressible) -> AssociationAggregate<OriginRowDecoder> {
        let aggregate = makeAggregate(.aggregate("SUM", [expression.sqlExpression]))
        if let column = expression as? ColumnExpression {
            let name = key.singularizedName

    ///     let infos: [TeamInfo] = try TeamInfo.fetchAll(db, request)
    ///
    ///     let teams: [Team] = try Team.having(Team.players.max(Column("score")) < 100).fetchAll(db)
    @available(*, deprecated, message: "Did you mean max(Column(...))? If not, prefer max(value.databaseValue) instead.") // swiftlint:disable:this line_length
    public func max(_ expression: SQLExpressible) -> AssociationAggregate<OriginRowDecoder> {
        let aggregate = makeAggregate(.aggregate("MAX", [expression.sqlExpression]))
        if let column = expression as? ColumnExpression {
