refactor(exporter, schema): 优化SQL构建逻辑以避免重复数据
- 移除BuildSQL函数中的冗余去重逻辑,简化SQL构建过程 - 更新多个表的JOIN逻辑,使用ROW_NUMBER()函数确保每个订单只保留最新记录,避免1:N重复 - 提升代码可读性,确保SQL构建逻辑清晰明了
This commit is contained in:
parent
ce547a50da
commit
1ee2b4bd79
|
|
@ -538,58 +538,6 @@ func BuildSQL(req BuildRequest, whitelist map[string]bool) (string, []interface{
|
||||||
sb.WriteString(" WHERE ")
|
sb.WriteString(" WHERE ")
|
||||||
sb.WriteString(strings.Join(where, " AND "))
|
sb.WriteString(strings.Join(where, " AND "))
|
||||||
}
|
}
|
||||||
needDedupe := false
|
|
||||||
if req.Datasource == "marketing" && req.MainTable == "order" && (need["order_voucher"] || need["voucher"] || need["voucher_batch"] || need["key_batch"] || need["code_batch"]) {
|
|
||||||
needDedupe = true
|
|
||||||
}
|
|
||||||
if req.Datasource == "ymt" && (req.MainTable == "order" || req.MainTable == "order_info") && (need["order_digit"] || need["order_voucher"] || need["voucher"] || need["voucher_batch"]) {
|
|
||||||
needDedupe = true
|
|
||||||
}
|
|
||||||
if needDedupe {
|
|
||||||
// Extract alias names in order
|
|
||||||
aliases := make([]string, 0, len(cols))
|
|
||||||
sources := make([]string, 0, len(cols))
|
|
||||||
for _, c := range cols {
|
|
||||||
pos := strings.LastIndex(c, " AS `")
|
|
||||||
if pos < 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
alias := c[pos+5:]
|
|
||||||
if len(alias) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if alias[len(alias)-1] == '`' {
|
|
||||||
alias = alias[:len(alias)-1]
|
|
||||||
}
|
|
||||||
aliases = append(aliases, alias)
|
|
||||||
parts := strings.Split(alias, ".")
|
|
||||||
src := ""
|
|
||||||
if len(parts) >= 1 {
|
|
||||||
src = parts[0]
|
|
||||||
}
|
|
||||||
sources = append(sources, src)
|
|
||||||
}
|
|
||||||
// 聚合时按别名分组:主表字段别名始终是 req.MainTable.order_number
|
|
||||||
pkAlias := req.MainTable + ".order_number"
|
|
||||||
var out strings.Builder
|
|
||||||
out.WriteString("SELECT ")
|
|
||||||
for i := range aliases {
|
|
||||||
if i > 0 {
|
|
||||||
out.WriteString(",")
|
|
||||||
}
|
|
||||||
alias := aliases[i]
|
|
||||||
src := sources[i]
|
|
||||||
if src == "order" {
|
|
||||||
out.WriteString("sub.`" + alias + "`")
|
|
||||||
} else {
|
|
||||||
out.WriteString("MIN(sub.`" + alias + "`) AS `" + alias + "`")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out.WriteString(" FROM (")
|
|
||||||
out.WriteString(sb.String())
|
|
||||||
out.WriteString(") AS sub GROUP BY sub.`" + pkAlias + "`")
|
|
||||||
return out.String(), args, nil
|
|
||||||
}
|
|
||||||
return sb.String(), args, nil
|
return sb.String(), args, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,28 +12,28 @@ func (marketingSchema) BuildJoins(need map[string]bool, main string) []string {
|
||||||
out = append(out, " LEFT JOIN `order_detail` ON `order_detail`.order_number = `order`.order_number")
|
out = append(out, " LEFT JOIN `order_detail` ON `order_detail`.order_number = `order`.order_number")
|
||||||
}
|
}
|
||||||
if need["order_cash"] {
|
if need["order_cash"] {
|
||||||
out = append(out, " LEFT JOIN `order_cash` ON `order_cash`.order_number = `order`.order_number")
|
out = append(out, " LEFT JOIN (SELECT * FROM (SELECT `order_cash`.*, ROW_NUMBER() OVER (PARTITION BY `order_cash`.order_number ORDER BY `order_cash`.id DESC) AS rn FROM `order_cash`) t WHERE t.rn = 1) AS `order_cash` ON `order_cash`.order_number = `order`.order_number")
|
||||||
}
|
}
|
||||||
if need["order_voucher"] {
|
if need["order_voucher"] {
|
||||||
out = append(out, " LEFT JOIN `order_voucher` ON `order_voucher`.order_number = `order`.order_number")
|
out = append(out, " LEFT JOIN (SELECT * FROM (SELECT `order_voucher`.*, ROW_NUMBER() OVER (PARTITION BY `order_voucher`.order_number ORDER BY `order_voucher`.id DESC) AS rn FROM `order_voucher`) t WHERE t.rn = 1) AS `order_voucher` ON `order_voucher`.order_number = `order`.order_number")
|
||||||
}
|
}
|
||||||
if need["plan"] || need["key_batch"] {
|
if need["plan"] || need["key_batch"] {
|
||||||
out = append(out, " LEFT JOIN `plan` ON `plan`.id = `order`.plan_id")
|
out = append(out, " LEFT JOIN `plan` ON `plan`.id = `order`.plan_id")
|
||||||
}
|
}
|
||||||
if need["key_batch"] {
|
if need["key_batch"] {
|
||||||
out = append(out, " LEFT JOIN `key_batch` ON `key_batch`.plan_id = `plan`.id")
|
out = append(out, " LEFT JOIN (SELECT * FROM (SELECT `key_batch`.*, ROW_NUMBER() OVER (PARTITION BY `key_batch`.plan_id ORDER BY `key_batch`.id DESC) AS rn FROM `key_batch`) t WHERE t.rn = 1) AS `key_batch` ON `key_batch`.plan_id = `plan`.id")
|
||||||
}
|
}
|
||||||
if need["code_batch"] {
|
if need["code_batch"] {
|
||||||
out = append(out, " LEFT JOIN `code_batch` ON `code_batch`.key_batch_id = `key_batch`.id")
|
out = append(out, " LEFT JOIN (SELECT * FROM (SELECT `code_batch`.*, ROW_NUMBER() OVER (PARTITION BY `code_batch`.key_batch_id ORDER BY `code_batch`.id DESC) AS rn FROM `code_batch`) t WHERE t.rn = 1) AS `code_batch` ON `code_batch`.key_batch_id = `key_batch`.id")
|
||||||
}
|
}
|
||||||
if need["voucher"] {
|
if need["voucher"] {
|
||||||
out = append(out, " LEFT JOIN `voucher` ON `voucher`.channel_activity_id = `order_voucher`.channel_activity_id")
|
out = append(out, " LEFT JOIN (SELECT * FROM (SELECT `voucher`.*, ROW_NUMBER() OVER (PARTITION BY `voucher`.channel_activity_id ORDER BY `voucher`.id DESC) AS rn FROM `voucher`) t WHERE t.rn = 1) AS `voucher` ON `voucher`.channel_activity_id = `order_voucher`.channel_activity_id")
|
||||||
}
|
}
|
||||||
if need["voucher_batch"] {
|
if need["voucher_batch"] {
|
||||||
out = append(out, " LEFT JOIN `voucher_batch` ON `voucher_batch`.voucher_id = `voucher`.id")
|
out = append(out, " LEFT JOIN (SELECT * FROM (SELECT `voucher_batch`.*, ROW_NUMBER() OVER (PARTITION BY `voucher_batch`.voucher_id ORDER BY `voucher_batch`.id DESC) AS rn FROM `voucher_batch`) t WHERE t.rn = 1) AS `voucher_batch` ON `voucher_batch`.voucher_id = `voucher`.id")
|
||||||
}
|
}
|
||||||
if need["merchant_key_send"] {
|
if need["merchant_key_send"] {
|
||||||
out = append(out, " LEFT JOIN `merchant_key_send` ON `order`.`key` = `merchant_key_send`.key")
|
out = append(out, " LEFT JOIN (SELECT * FROM (SELECT `merchant_key_send`.*, ROW_NUMBER() OVER (PARTITION BY `merchant_key_send`.key ORDER BY `merchant_key_send`.id DESC) AS rn FROM `merchant_key_send`) t WHERE t.rn = 1) AS `merchant_key_send` ON `order`.`key` = `merchant_key_send`.key")
|
||||||
}
|
}
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,13 +52,14 @@ func (s ymtSchema) MapField(t, f string) (string, bool) {
|
||||||
func (s ymtSchema) BuildJoins(need map[string]bool, main string) []string {
|
func (s ymtSchema) BuildJoins(need map[string]bool, main string) []string {
|
||||||
out := []string{}
|
out := []string{}
|
||||||
if need["order_cash"] {
|
if need["order_cash"] {
|
||||||
out = append(out, " LEFT JOIN `order_cash` ON `order_cash`.order_no = `order_info`.order_no")
|
// avoid 1:N duplication: keep latest row per order_no (no GROUP BY)
|
||||||
|
out = append(out, " LEFT JOIN (SELECT * FROM (SELECT `order_cash`.*, ROW_NUMBER() OVER (PARTITION BY `order_cash`.order_no ORDER BY `order_cash`.id DESC) AS rn FROM `order_cash`) t WHERE t.rn = 1) AS `order_cash` ON `order_cash`.order_no = `order_info`.order_no")
|
||||||
}
|
}
|
||||||
if need["order_voucher"] {
|
if need["order_voucher"] {
|
||||||
out = append(out, " LEFT JOIN `order_voucher` ON `order_voucher`.order_no = `order_info`.order_no")
|
out = append(out, " LEFT JOIN (SELECT * FROM (SELECT `order_voucher`.*, ROW_NUMBER() OVER (PARTITION BY `order_voucher`.order_no ORDER BY `order_voucher`.id DESC) AS rn FROM `order_voucher`) t WHERE t.rn = 1) AS `order_voucher` ON `order_voucher`.order_no = `order_info`.order_no")
|
||||||
}
|
}
|
||||||
if need["order_digit"] {
|
if need["order_digit"] {
|
||||||
out = append(out, " LEFT JOIN `order_digit` ON `order_digit`.order_no = `order_info`.order_no")
|
out = append(out, " LEFT JOIN (SELECT * FROM (SELECT `order_digit`.*, ROW_NUMBER() OVER (PARTITION BY `order_digit`.order_no ORDER BY `order_digit`.id DESC) AS rn FROM `order_digit`) t WHERE t.rn = 1) AS `order_digit` ON `order_digit`.order_no = `order_info`.order_no")
|
||||||
}
|
}
|
||||||
if need["goods_voucher_batch"] {
|
if need["goods_voucher_batch"] {
|
||||||
out = append(out, " LEFT JOIN `goods_voucher_batch` ON `goods_voucher_batch`.channel_batch_no = `order_voucher`.channel_batch_no")
|
out = append(out, " LEFT JOIN `goods_voucher_batch` ON `goods_voucher_batch`.channel_batch_no = `order_voucher`.channel_batch_no")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue