def sqlbins(column, bins, join="\n"):
    """
    Returns a SQL string expression for binning values

    Parameters
    ==========
    column : str
        The column to bin

    bins : list of int or float
        - Need at least 2 values to create a bin
        - e.g. bins = [0, 1, 5, 10]; the bins created will be:
          [0-1), [1-5), [5-10), 10+

    Returns
    =======
    a SQL string expression

    e.g. for column = "A" and bins = [0, 1, 5], the returned SQL expression will be:
         "case when A < 0 then '(-Inf, 0)' when A >= 0 and A < 1 then '[0, 1)' when A >= 1 and A < 5 then '[1, 5)' else '[5, +Inf)'"
    """
    sql = ["case"]
    sql += [f"when {column} < {bins[0]} then '(-Inf, {bins[0]})'"]
    for i,b in enumerate(bins[1:]):
        sql += [f"when {column} >= {bins[i]} and {column} < {b} then '[{bins[i]}, {bins[i+1]})'"]
    sql += [f"when {column} >= {bins[-1]} then '[{bins[-1]}, +Inf)'"]
    sql += [f"else 'NaN' end"]
    sql = join.join(sql)
    return sql