206 lines
5.0 KiB
Go
206 lines
5.0 KiB
Go
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"
|
|
)
|