-- ============================================================================ -- پیش‌بررسی سوم — فقط دو سؤال باقی‌مانده -- ============================================================================ -- -- ⚠️ فقط SELECT COUNT. صفر INSERT/UPDATE/DELETE. هیچ ستون متنی در خروجی. -- -- اجرا: -- mysql -u USER -p -h HOST -P 3305 oapi < migration-precheck-3.sql > out3.txt -- -- مرجع: docs/DATA-MIGRATION-MAP.md §۵.۹ -- ============================================================================ -- --------------------------------------------------------------------------- -- سؤال: new_city باید به cityId نگاشت شود یا ستون جدا بگیرد؟ -- -- تصمیم مالک: «یا در فیلد شهر بنشیند یا در یک فیلد آدرس متنی مپ شود». -- کدام‌یک، به این بستگی دارد که آیا این ۱۷۶ ردیف city_id هم دارند یا نه: -- -- فقط new_city (city_id تهی) → ستون متنی لازم است، چون شهر در جدول cities نیست -- هر دو را دارند → new_city تکراری است، می‌توان رهایش کرد -- --------------------------------------------------------------------------- SELECT '=== new_city vs city_id ===' AS section; SELECT SUM(new_city IS NOT NULL AND new_city <> '' AND city_id IS NULL) AS only_new_city, SUM(new_city IS NOT NULL AND new_city <> '' AND city_id IS NOT NULL) AS both_set, SUM((new_city IS NULL OR new_city = '') AND city_id IS NOT NULL) AS only_city_id, SUM((new_city IS NULL OR new_city = '') AND city_id IS NULL) AS neither FROM customers WHERE deleted_at IS NULL; -- از آن ۱۷۶ ردیف، چندتا متنی‌شان با عنوان یک شهر موجود در `cities` یکی است؟ -- اگر بالا باشد، اکثرشان قابل تبدیل به city_id هستند و ستون متنی لازم نیست. SELECT 'new_city matches an existing cities.title' AS metric, COUNT(*) AS n FROM customers c -- The two columns have different collations (unicode_ci vs general_ci), so -- both sides are pinned to one; without it MySQL refuses the comparison. JOIN cities ci ON TRIM(ci.title) COLLATE utf8mb4_general_ci = TRIM(c.new_city) COLLATE utf8mb4_general_ci WHERE c.deleted_at IS NULL AND c.new_city IS NOT NULL AND c.new_city <> '' AND c.city_id IS NULL; -- چند مقدار متمایز؟ (عدد است، نه متن — اگر کم باشد نگاشت دستی ممکن است) SELECT 'distinct_new_city_values' AS metric, COUNT(DISTINCT TRIM(new_city)) AS n FROM customers WHERE deleted_at IS NULL AND new_city IS NOT NULL AND new_city <> ''; -- --------------------------------------------------------------------------- -- سؤال: birth_date — آیا تاریخ‌ها معتبرند؟ -- -- ستون timestamp است. ولی اگر تاریخ جلالی به‌اشتباه به‌عنوان میلادی -- ذخیره شده باشد، سال‌ها ۱۳xx می‌شوند که در timestamp جا نمی‌شوند، -- یا به مقادیر عجیب تبدیل شده‌اند. -- --------------------------------------------------------------------------- SELECT '=== birth_date sanity ===' AS section; SELECT COUNT(birth_date) AS total_set, SUM(YEAR(birth_date) < 1900) AS year_before_1900, SUM(YEAR(birth_date) BETWEEN 1900 AND 1950) AS year_1900_1950, SUM(YEAR(birth_date) BETWEEN 1951 AND 2010) AS year_1951_2010, SUM(YEAR(birth_date) > 2010) AS year_after_2010, CAST(MIN(YEAR(birth_date)) AS CHAR) AS min_year, CAST(MAX(YEAR(birth_date)) AS CHAR) AS max_year FROM customers WHERE deleted_at IS NULL; SELECT '=== END ===' AS section;