206 lines
5.0 KiB
Go
Raw Normal View History

2022-01-26 16:40:50 +08:00
package utils
import (
"fmt"
"strconv"
"strings"
"sync/atomic"
)
type CountType = string
const SPLIT = "$$$xwl$$$"
const (
UserNum = "1"
AllSum = "2"
AvgCount = "3"
AvgSumByUser = "4"
MiddleCount = "5"
MaxCount = "6"
MinCount = "7"
DistincCount = "8"
MiddleCount5 = "9"
MiddleCount10 = "10"
MiddleCount20 = "11"
MiddleCount25 = "12"
MiddleCount30 = "13"
MiddleCount40 = "14"
MiddleCount60 = "15"
MiddleCount70 = "16"
MiddleCount75 = "17"
MiddleCount80 = "18"
MiddleCount90 = "19"
MiddleCount95 = "20"
MiddleCount99 = "21"
AllCount = "A1"
ClickUserNum = "A2"
AvgCountByUser = "A3"
)
func allCount(col string) string {
if col == Default {
return toString("count()")
}
return toString(fmt.Sprintf("count(%s)", col))
}
func clickUserNum(col string) string {
if col == Default {
return toString(Round(NaN2Zero("COUNT(DISTINCT xwl_distinct_id)")))
}
return toString(Round(NaN2Zero(fmt.Sprintf("COUNT(DISTINCT %s)", col))))
}
var IntPropQuotas = map[string]string{
AllSum: "总和",
AvgCount: "均值",
AvgSumByUser: "人均值",
MaxCount: "最大值",
MinCount: "最小值",
DistincCount: "去重数",
MiddleCount: "中位数",
MiddleCount5: "5分位数",
MiddleCount10: "10分位数",
MiddleCount20: "20分位数",
MiddleCount25: "25分位数",
MiddleCount30: "30分位数",
MiddleCount40: "40分位数",
MiddleCount60: "60分位数",
MiddleCount70: "70分位数",
MiddleCount75: "75分位数",
MiddleCount80: "80分位数",
MiddleCount90: "90分位数",
MiddleCount95: "95分位数",
MiddleCount99: "99分位数",
}
var StringPropQuotas = map[string]string{
DistincCount: "去重数",
}
const Default = "默认"
type getCountCol = func(col string) string
var autoAddId int32
func NaN2Zero(fn string) string {
autoAddId = atomic.AddInt32(&autoAddId, 1)
uuid := "col_" + strconv.Itoa(int(autoAddId))
return fmt.Sprintf("if(isInfinite(if(isNaN(%s as %s),0,%s)),0,%s)", fn, uuid, uuid, uuid)
}
func toString(fn string) string {
return fmt.Sprintf("toString(%s)", fn)
}
func Round(fn string) string {
return fmt.Sprintf("round(%s,2)", fn)
}
func Divide(fn string) string {
return fmt.Sprintf("divide(%s)", fn)
}
func ToFloat32OrZero(fn string) string {
return fmt.Sprintf("toFloat64OrZero(CAST(%s,'String'))", fn)
}
var CountTypMap = map[CountType]getCountCol{
UserNum: func(col string) string {
if col == Default {
return toString("count()")
}
return toString(fmt.Sprintf("count(%s)", col))
},
AllSum: func(col string) string {
return toString(Round(NaN2Zero(fmt.Sprintf("sum(%s)", col))))
},
AvgCount: func(col string) string {
return toString(Round(NaN2Zero(fmt.Sprintf(" avg(%s) ", col))))
},
AvgSumByUser: func(col string) string {
return toString(Round(NaN2Zero(fmt.Sprintf("SUM(%s)/COUNT(DISTINCT xwl_distinct_id)", col))))
},
MiddleCount: func(col string) string {
return toString(NaN2Zero(fmt.Sprintf("quantile(%s)", col)))
},
MaxCount: func(col string) string {
return toString(Round(NaN2Zero(fmt.Sprintf("max(%s)", col))))
},
MinCount: func(col string) string {
return toString(Round(NaN2Zero(fmt.Sprintf("min(%s)", col))))
},
DistincCount: func(col string) string {
return toString(Round(NaN2Zero(fmt.Sprintf("count(DISTINCT %s)", col))))
},
AllCount: allCount,
ClickUserNum: clickUserNum,
AvgCountByUser: func(col string) string {
if col == Default {
return toString(Round(NaN2Zero(fmt.Sprintf("%s/%s", ToFloat32OrZero(allCount(col)), ToFloat32OrZero(clickUserNum(col))))))
}
arr := strings.Split(col, SPLIT)
return toString(Round(NaN2Zero(fmt.Sprintf("%s/%s", ToFloat32OrZero(allCount(arr[0])), ToFloat32OrZero(clickUserNum(arr[1]))))))
},
MiddleCount5: func(col string) string {
return toString(getQuantile(0.05, col))
},
MiddleCount10: func(col string) string {
return toString(getQuantile(0.1, col))
},
MiddleCount20: func(col string) string {
return toString(getQuantile(0.2, col))
},
MiddleCount25: func(col string) string {
return toString(getQuantile(0.25, col))
},
MiddleCount30: func(col string) string {
return toString(getQuantile(0.3, col))
},
MiddleCount40: func(col string) string {
return toString(getQuantile(0.4, col))
},
MiddleCount60: func(col string) string {
return toString(getQuantile(0.6, col))
},
MiddleCount70: func(col string) string {
return toString(getQuantile(0.7, col))
},
MiddleCount75: func(col string) string {
return toString(getQuantile(0.75, col))
},
MiddleCount80: func(col string) string {
return toString(getQuantile(0.8, col))
},
MiddleCount90: func(col string) string {
return toString(getQuantile(0.9, col))
},
MiddleCount95: func(col string) string {
return toString(getQuantile(0.95, col))
},
MiddleCount99: func(col string) string {
return toString(getQuantile(0.99, col))
},
}
func getQuantile(sum float64, col string) string {
return NaN2Zero(fmt.Sprintf(" quantile(%v)(%s) ", sum, col))
}
const (
TwoDecimalPlaces = "1"
Percentage = "2"
Rounding = "3"
)