institutional-trader/backend/database/fix_time_format_simple.sql

92 lines
3.5 KiB
SQL

-- Simple Fix for Malformed Time Entries
-- Fixes times like "34 AM" (missing hour) by adding a default hour
-- Run this in your PostgreSQL database
-- Step 1: Check for malformed entries
SELECT
"CreatedDate",
"CreatedTime",
COUNT(*) as count
FROM "OptionsFlow_monthly"
WHERE "CreatedTime" IS NOT NULL
AND "CreatedTime"::text ~ '^\d{2}\s*(AM|PM)$' -- Two digits + AM/PM (likely minute only)
AND "CreatedTime"::text !~ '^\d{1,2}:\d{2}' -- No colon (missing hour)
GROUP BY "CreatedDate", "CreatedTime"
ORDER BY count DESC
LIMIT 50;
-- Step 2: Fix entries where time is just "XX AM" or "XX PM" (missing hour)
-- Strategy: If the number is > 12, it's definitely a minute, so add hour 9 (AM) or 1 (PM)
-- If number <= 12, check context or default to 9 AM / 1 PM
UPDATE "OptionsFlow_monthly"
SET "CreatedTime" =
CASE
-- Pattern: "34 AM" -> "9:34 AM" (number > 12, must be minutes)
WHEN "CreatedTime"::text ~ '^(\d{2})\s*AM$'
AND (REGEXP_REPLACE("CreatedTime"::text, '^(\d{2})\s*AM$', '\1'))::int > 12
THEN
'9:' || REGEXP_REPLACE("CreatedTime"::text, '^(\d{2})\s*AM$', '\1') || ':00 AM'
-- Pattern: "34 PM" -> "1:34 PM" (number > 12, must be minutes)
WHEN "CreatedTime"::text ~ '^(\d{2})\s*PM$'
AND (REGEXP_REPLACE("CreatedTime"::text, '^(\d{2})\s*PM$', '\1'))::int > 12
THEN
'1:' || REGEXP_REPLACE("CreatedTime"::text, '^(\d{2})\s*PM$', '\1') || ':00 PM'
-- Pattern: "12 AM" or less -> "9:XX AM" (could be hour or minute, default to 9 AM)
WHEN "CreatedTime"::text ~ '^(\d{1,2})\s*AM$'
AND (REGEXP_REPLACE("CreatedTime"::text, '^(\d{1,2})\s*AM$', '\1'))::int <= 12
THEN
'9:' || LPAD(REGEXP_REPLACE("CreatedTime"::text, '^(\d{1,2})\s*AM$', '\1'), 2, '0') || ':00 AM'
-- Pattern: "12 PM" or less -> "1:XX PM" (could be hour or minute, default to 1 PM)
WHEN "CreatedTime"::text ~ '^(\d{1,2})\s*PM$'
AND (REGEXP_REPLACE("CreatedTime"::text, '^(\d{1,2})\s*PM$', '\1'))::int <= 12
THEN
'1:' || LPAD(REGEXP_REPLACE("CreatedTime"::text, '^(\d{1,2})\s*PM$', '\1'), 2, '0') || ':00 PM'
-- Pattern: ":34 AM" (missing hour, has colon) -> "9:34 AM"
WHEN "CreatedTime"::text ~ '^:(\d{1,2})\s*AM$'
THEN
'9:' || LPAD(REGEXP_REPLACE("CreatedTime"::text, '^:(\d{1,2})\s*AM$', '\1'), 2, '0') || ':00 AM'
-- Pattern: ":34 PM" (missing hour, has colon) -> "1:34 PM"
WHEN "CreatedTime"::text ~ '^:(\d{1,2})\s*PM$'
THEN
'1:' || LPAD(REGEXP_REPLACE("CreatedTime"::text, '^:(\d{1,2})\s*PM$', '\1'), 2, '0') || ':00 PM'
ELSE "CreatedTime" -- Keep as-is if doesn't match patterns
END
WHERE "CreatedTime" IS NOT NULL
AND (
-- Match patterns: "XX AM/PM" without colon, or ":XX AM/PM"
("CreatedTime"::text ~ '^\d{1,2}\s*(AM|PM)$' AND "CreatedTime"::text !~ '^\d{1,2}:\d{2}')
OR "CreatedTime"::text ~ '^:\d{1,2}\s*(AM|PM)$'
);
-- Step 3: Verify the fix
SELECT
COUNT(*) as remaining_malformed,
'Remaining entries with malformed time format' as description
FROM "OptionsFlow_monthly"
WHERE "CreatedTime" IS NOT NULL
AND (
("CreatedTime"::text ~ '^\d{1,2}\s*(AM|PM)$' AND "CreatedTime"::text !~ '^\d{1,2}:\d{2}')
OR "CreatedTime"::text ~ '^:\d{1,2}\s*(AM|PM)$'
);
-- Step 4: Show sample of fixed entries
SELECT
"CreatedDate",
"CreatedTime",
"Symbol",
COUNT(*) as count
FROM "OptionsFlow_monthly"
WHERE "CreatedTime" IS NOT NULL
AND "CreatedTime"::text ~ '^\d{1,2}:\d{2}:\d{2}\s*(AM|PM)$' -- Properly formatted now
GROUP BY "CreatedDate", "CreatedTime", "Symbol"
ORDER BY "CreatedDate" DESC
LIMIT 20;