//go:build ignore package main import ( "fmt" "gorm.io/driver/mysql" "gorm.io/gorm" ) func main() { dsn := "root:bindbox2025kdy@tcp(150.158.78.154:3306)/dev_game?charset=utf8mb4&parseTime=True&loc=Local" db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) if err != nil { fmt.Println("连接失败:", err) return } filter := "users.deleted_at IS NULL AND orders.status = 2 AND orders.total_amount > 0 AND orders.actual_amount > 0 AND orders.source_type IN (2,3,4) AND (orders.ext_order_id = '' OR orders.ext_order_id IS NULL)" // 1. 各字段使用分布 type FieldStats struct { Label string Count int64 Sum int64 } fmt.Println("========== GMV 支付方式拆分数据探查 ==========") fmt.Println() // actual_amount (现金) var cash FieldStats db.Table("orders").Joins("JOIN users ON users.id = orders.user_id"). Select("'现金(actual_amount)' as label, COUNT(*) as count, COALESCE(SUM(actual_amount),0) as sum"). Where(filter).Scan(&cash) // discount_amount (优惠券) var coupon FieldStats db.Table("orders").Joins("JOIN users ON users.id = orders.user_id"). Select("'优惠券(discount_amount)' as label, COUNT(*) as count, COALESCE(SUM(discount_amount),0) as sum"). Where(filter + " AND discount_amount > 0").Scan(&coupon) // points_amount (积分) var points FieldStats db.Table("orders").Joins("JOIN users ON users.id = orders.user_id"). Select("'积分(points_amount)' as label, COUNT(*) as count, COALESCE(SUM(points_amount),0) as sum"). Where(filter + " AND points_amount > 0").Scan(&points) // 道具卡 (item_card_id > 0) var itemCard FieldStats db.Table("orders").Joins("JOIN users ON users.id = orders.user_id"). Select("'道具卡(item_card_id)' as label, COUNT(*) as count, 0 as sum"). Where(filter + " AND item_card_id > 0").Scan(&itemCard) // 总 GMV var totalGMV FieldStats db.Table("orders").Joins("JOIN users ON users.id = orders.user_id"). Select("'总GMV(total_amount)' as label, COUNT(*) as count, COALESCE(SUM(total_amount),0) as sum"). Where(filter).Scan(&totalGMV) fmt.Printf("%-25s %8s %14s\n", "字段", "订单数", "金额(元)") fmt.Println("--------------------------------------------------") for _, f := range []FieldStats{totalGMV, cash, coupon, points, itemCard} { fmt.Printf("%-25s %8d %14.2f\n", f.Label, f.Count, float64(f.Sum)/100) } // 2. 验证: total = actual + discount + points ? fmt.Println() fmt.Println("========== 验证: total_amount = actual + discount + points ? ==========") type MismatchRow struct { Count int64 } var mismatch MismatchRow db.Table("orders").Joins("JOIN users ON users.id = orders.user_id"). Select("COUNT(*) as count"). Where(filter + " AND total_amount != (actual_amount + discount_amount + points_amount)"). Scan(&mismatch) fmt.Printf(" 不等式成立的订单数: %d\n", mismatch.Count) if mismatch.Count > 0 { type DetailRow struct { ID int64 TotalAmount int64 ActualAmount int64 DiscountAmount int64 PointsAmount int64 Diff int64 } var details []DetailRow db.Table("orders").Joins("JOIN users ON users.id = orders.user_id"). Select("orders.id, orders.total_amount, orders.actual_amount, orders.discount_amount, orders.points_amount, (orders.total_amount - orders.actual_amount - orders.discount_amount - orders.points_amount) as diff"). Where(filter + " AND total_amount != (actual_amount + discount_amount + points_amount)"). Limit(5).Scan(&details) fmt.Println(" 抽样:") for _, d := range details { fmt.Printf(" #%d total=%d actual=%d discount=%d points=%d diff=%d\n", d.ID, d.TotalAmount, d.ActualAmount, d.DiscountAmount, d.PointsAmount, d.Diff) } } // 3. 次卡购买订单的支付方式拆分 fmt.Println() fmt.Println("========== source_type=4 购买次卡的支付方式 ==========") var gpCash, gpCoupon, gpPoints FieldStats gpFilter := "users.deleted_at IS NULL AND orders.status = 2 AND orders.total_amount > 0 AND orders.actual_amount > 0 AND orders.source_type = 4 AND orders.order_no LIKE 'GP%' AND (orders.ext_order_id = '' OR orders.ext_order_id IS NULL)" db.Table("orders").Joins("JOIN users ON users.id = orders.user_id"). Select("'现金' as label, COUNT(*) as count, COALESCE(SUM(actual_amount),0) as sum"). Where(gpFilter).Scan(&gpCash) db.Table("orders").Joins("JOIN users ON users.id = orders.user_id"). Select("'优惠券' as label, COUNT(*) as count, COALESCE(SUM(discount_amount),0) as sum"). Where(gpFilter + " AND discount_amount > 0").Scan(&gpCoupon) db.Table("orders").Joins("JOIN users ON users.id = orders.user_id"). Select("'积分' as label, COUNT(*) as count, COALESCE(SUM(points_amount),0) as sum"). Where(gpFilter + " AND points_amount > 0").Scan(&gpPoints) fmt.Printf(" 现金: %d单 %.2f元\n", gpCash.Count, float64(gpCash.Sum)/100) fmt.Printf(" 优惠券: %d单 %.2f元\n", gpCoupon.Count, float64(gpCoupon.Sum)/100) fmt.Printf(" 积分: %d单 %.2f元\n", gpPoints.Count, float64(gpPoints.Sum)/100) // 4. 按 source_type 拆分 GMV 构成 fmt.Println() fmt.Println("========== 按游戏类型 × 支付方式 ==========") srcNames := map[int]string{2: "小程序抽奖", 3: "对对碰", 4: "一番赏/次卡"} for _, st := range []int{2, 3, 4} { stFilter := fmt.Sprintf("users.deleted_at IS NULL AND orders.status = 2 AND orders.total_amount > 0 AND orders.actual_amount > 0 AND orders.source_type = %d AND (orders.ext_order_id = '' OR orders.ext_order_id IS NULL)", st) var total, actual, discount, pts FieldStats db.Table("orders").Joins("JOIN users ON users.id = orders.user_id"). Select("'total' as label, COUNT(*) as count, COALESCE(SUM(total_amount),0) as sum"). Where(stFilter).Scan(&total) db.Table("orders").Joins("JOIN users ON users.id = orders.user_id"). Select("'actual' as label, COUNT(*) as count, COALESCE(SUM(actual_amount),0) as sum"). Where(stFilter).Scan(&actual) db.Table("orders").Joins("JOIN users ON users.id = orders.user_id"). Select("'discount' as label, COUNT(*) as count, COALESCE(SUM(discount_amount),0) as sum"). Where(stFilter).Scan(&discount) db.Table("orders").Joins("JOIN users ON users.id = orders.user_id"). Select("'points' as label, COUNT(*) as count, COALESCE(SUM(points_amount),0) as sum"). Where(stFilter).Scan(&pts) fmt.Printf(" %s(type=%d): %d单 GMV=%.2f 现金=%.2f 优惠券=%.2f 积分=%.2f\n", srcNames[st], st, total.Count, float64(total.Sum)/100, float64(actual.Sum)/100, float64(discount.Sum)/100, float64(pts.Sum)/100) } }