Perform a groupby on a table and return an aggregation on a single column.

    This depends on some request parameters in the URL.
    "column" and "agg" must always be present, and one of "by" or "level"
    must be present. "column" is the table column on which aggregation will
    be performed, "agg" is the aggregation that will be performed, and
    "by"/"level" define how to group the data.

    Supported "agg" parameters are: mean, median, std, sum, and size.

def table_groupbyagg(table_name):
    """
    Perform a groupby on a table and return an aggregation on a single column.

    This depends on some request parameters in the URL.
    "column" and "agg" must always be present, and one of "by" or "level"
    must be present. "column" is the table column on which aggregation will
    be performed, "agg" is the aggregation that will be performed, and
    "by"/"level" define how to group the data.

    Supported "agg" parameters are: mean, median, std, sum, and size.

    """
    table = orca.get_table(table_name)

    # column to aggregate
    column = request.args.get('column', None)
    if not column or column not in table.columns:
        abort(400)

    # column or index level to group by
    by = request.args.get('by', None)
    level = request.args.get('level', None)
    if (not by and not level) or (by and level):
        abort(400)

    # aggregation type
    agg = request.args.get('agg', None)
    if not agg or agg not in _GROUPBY_AGG_MAP:
        abort(400)

    column = table.get_column(column)

    # level can either be an integer level number or a string level name.
    # try converting to integer, but if that doesn't work
    # we go ahead with the string.
    if level:
        try:
            level = int(level)
        except ValueError:
            pass
        gby = column.groupby(level=level)
    else:
        by = table.get_column(by)
        gby = column.groupby(by)

    result = _GROUPBY_AGG_MAP[agg](gby)

    return (
        result.to_json(orient='split', date_format='iso'),
        200,
        {'Content-Type': 'application/json'})