diff --git a/cmd/consolidate-duplicate-product-warehouses/main.go b/cmd/consolidate-duplicate-product-warehouses/main.go index f77979b7..91e7ced2 100644 --- a/cmd/consolidate-duplicate-product-warehouses/main.go +++ b/cmd/consolidate-duplicate-product-warehouses/main.go @@ -120,27 +120,42 @@ func findDuplicateProductWarehouses(ctx context.Context, db *gorm.DB, opts *opti } query := fmt.Sprintf(` +WITH duplicates AS ( + SELECT + pw.warehouse_id, + w.name AS warehouse_name, + pw.product_id, + p.name AS product_name, + COALESCE(a.name, 'N/A') AS area_name, + COALESCE(l.name, 'N/A') AS location_name, + pw.id, + pw.qty, + MIN(pw.id) OVER (PARTITION BY pw.warehouse_id, pw.product_id) AS survivor_id, + COUNT(*) OVER (PARTITION BY pw.warehouse_id, pw.product_id) AS duplicate_count, + SUM(pw.qty) OVER (PARTITION BY pw.warehouse_id, pw.product_id) AS total_qty + FROM product_warehouses pw + JOIN warehouses w ON w.id = pw.warehouse_id + JOIN products p ON p.id = pw.product_id + LEFT JOIN locations l ON l.id = w.location_id + LEFT JOIN areas a ON a.id = l.area_id + %s +) SELECT - pw.warehouse_id, - w.name AS warehouse_name, - pw.product_id, - p.name AS product_name, - COALESCE(a.name, 'N/A') AS area_name, - COALESCE(l.name, 'N/A') AS location_name, - MIN(pw.id) AS survivor_id, - (SELECT qty FROM product_warehouses WHERE warehouse_id = pw.warehouse_id AND product_id = pw.product_id AND id = MIN(pw.id)) AS survivor_qty, - COUNT(*) - 1 AS absorbed_count, - SUM(pw.qty) AS total_merged_qty, - STRING_AGG(pw.id::text, ', ' ORDER BY pw.id::text) FILTER (WHERE pw.id <> MIN(pw.id)) AS absorbed_ids -FROM product_warehouses pw -JOIN warehouses w ON w.id = pw.warehouse_id -JOIN products p ON p.id = pw.product_id -LEFT JOIN locations l ON l.id = w.location_id -LEFT JOIN areas a ON a.id = l.area_id -%s -GROUP BY pw.warehouse_id, w.name, pw.product_id, p.name, a.name, l.name -HAVING COUNT(*) > 1 -ORDER BY a.name, l.name, w.name, p.name + warehouse_id, + warehouse_name, + product_id, + product_name, + area_name, + location_name, + survivor_id, + (SELECT qty FROM duplicates d2 WHERE d2.id = survivor_id LIMIT 1) AS survivor_qty, + duplicate_count - 1 AS absorbed_count, + total_qty AS total_merged_qty, + STRING_AGG(id::text, ', ' ORDER BY id::text) FILTER (WHERE id <> survivor_id) AS absorbed_ids +FROM duplicates +WHERE duplicate_count > 1 +GROUP BY warehouse_id, warehouse_name, product_id, product_name, area_name, location_name, survivor_id, total_qty, duplicate_count +ORDER BY area_name, location_name, warehouse_name, product_name `, filters) rows := make([]duplicateGroup, 0)