refactor(exporter, schema): 优化SQL构建逻辑以支持最新数据行的关联
- 更新BuildSQL和BuildJoins函数,移除ROW_NUMBER()函数,改为使用子查询确保每个订单只保留最新记录,避免1:N重复 - 增强JOIN逻辑,确保在YMT和其他数据源中正确关联最新的订单现金、代金券和批次信息 - 提升代码可读性,确保SQL构建逻辑清晰明了
This commit is contained in:
parent
70680061e2
commit
5bb83e1875
|
|
@ -97,10 +97,7 @@ func BuildSQL(req BuildRequest, whitelist map[string]bool) (string, []interface{
|
|||
cols = append(cols, constants.BuildCaseWhen("order", "pay_status", constants.MarketingPayStatus, "order.pay_status"))
|
||||
continue
|
||||
}
|
||||
if req.Datasource == "marketing" && f == "card_code" {
|
||||
cols = append(cols, "CASE WHEN LENGTH(`order`.card_code) > 10 THEN CONCAT(SUBSTRING(`order`.card_code,1,6),'****',SUBSTRING(`order`.card_code, LENGTH(`order`.card_code)-3, 4)) ELSE `order`.card_code END AS `order.card_code`")
|
||||
continue
|
||||
}
|
||||
// card_code: export raw value (no masking) per business requirement
|
||||
}
|
||||
if req.Datasource == "ymt" && t == "order" {
|
||||
if f == "type" {
|
||||
|
|
@ -568,6 +565,21 @@ func BuildCountSQL(req BuildRequest, whitelist map[string]bool) (string, []inter
|
|||
need[tbl] = true
|
||||
}
|
||||
}
|
||||
//补齐链式关联过滤所需的 JOIN(只用于 COUNT)
|
||||
if _, ok := req.Filters["order_cash_cash_activity_id_eq"]; ok {
|
||||
need["order_cash"] = true
|
||||
}
|
||||
if _, ok := req.Filters["order_voucher_channel_activity_id_eq"]; ok {
|
||||
need["order_voucher"] = true
|
||||
}
|
||||
if _, ok := req.Filters["voucher_batch_channel_activity_id_eq"]; ok {
|
||||
need["voucher_batch"] = true
|
||||
need["voucher"] = true
|
||||
need["order_voucher"] = true
|
||||
}
|
||||
if _, ok := req.Filters["merchant_out_biz_no_eq"]; ok {
|
||||
need["merchant_key_send"] = true
|
||||
}
|
||||
// normalize merchant_id_eq / reseller_id_eq for YMT: skip 0/空, 非零转为 merchant_id_in 以便与 creator_in 做 OR
|
||||
if v, ok := req.Filters["merchant_id_eq"]; ok {
|
||||
if isZeroID(v) {
|
||||
|
|
|
|||
|
|
@ -12,28 +12,29 @@ 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")
|
||||
}
|
||||
if need["order_cash"] {
|
||||
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")
|
||||
// MySQL 5.7: no window functions; keep latest row by id via correlated subquery (no GROUP BY)
|
||||
out = append(out, " LEFT JOIN `order_cash` ON `order_cash`.id = (SELECT MAX(oc2.id) FROM `order_cash` oc2 WHERE oc2.order_number = `order`.order_number)")
|
||||
}
|
||||
if need["order_voucher"] {
|
||||
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")
|
||||
out = append(out, " LEFT JOIN `order_voucher` ON `order_voucher`.id = (SELECT MAX(ov2.id) FROM `order_voucher` ov2 WHERE ov2.order_number = `order`.order_number)")
|
||||
}
|
||||
if need["plan"] || need["key_batch"] {
|
||||
out = append(out, " LEFT JOIN `plan` ON `plan`.id = `order`.plan_id")
|
||||
}
|
||||
if need["key_batch"] {
|
||||
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")
|
||||
out = append(out, " LEFT JOIN `key_batch` ON `key_batch`.plan_id = `plan`.id")
|
||||
}
|
||||
if need["code_batch"] {
|
||||
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")
|
||||
out = append(out, " LEFT JOIN `code_batch` ON `code_batch`.key_batch_id = `key_batch`.id")
|
||||
}
|
||||
if need["voucher"] {
|
||||
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")
|
||||
out = append(out, " LEFT JOIN `voucher` ON `voucher`.id = (SELECT MAX(v2.id) FROM `voucher` v2 WHERE v2.channel_activity_id = `order_voucher`.channel_activity_id)")
|
||||
}
|
||||
if need["voucher_batch"] {
|
||||
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")
|
||||
out = append(out, " LEFT JOIN `voucher_batch` ON `voucher_batch`.id = (SELECT MAX(vb2.id) FROM `voucher_batch` vb2 WHERE vb2.voucher_id = `voucher`.id)")
|
||||
}
|
||||
if need["merchant_key_send"] {
|
||||
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")
|
||||
out = append(out, " LEFT JOIN `merchant_key_send` ON `order`.`key` = `merchant_key_send`.key")
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,14 +52,13 @@ func (s ymtSchema) MapField(t, f string) (string, bool) {
|
|||
func (s ymtSchema) BuildJoins(need map[string]bool, main string) []string {
|
||||
out := []string{}
|
||||
if need["order_cash"] {
|
||||
// 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")
|
||||
out = append(out, " LEFT JOIN `order_cash` ON `order_cash`.order_no = `order_info`.order_no")
|
||||
}
|
||||
if need["order_voucher"] {
|
||||
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")
|
||||
out = append(out, " LEFT JOIN `order_voucher` ON `order_voucher`.order_no = `order_info`.order_no")
|
||||
}
|
||||
if need["order_digit"] {
|
||||
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")
|
||||
out = append(out, " LEFT JOIN `order_digit` ON `order_digit`.order_no = `order_info`.order_no")
|
||||
}
|
||||
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")
|
||||
|
|
|
|||
Loading…
Reference in New Issue