1. Faro

Nivel 6 · Analiza un feed de transportista con formatos de fecha mezclados

La solicitud

De Kevin Brooks, Gerente de Operaciones

“Nuestro transportista envía las fechas de entrega como texto libre y cada depósito las escribe distinto. Para los pedidos de Halloween de esta muestra, necesito el tiempo de entrega en días, un código de referencia para cada envío y una marca en todo lo que no puedas leer para que lo persiga.”

Tu objetivo

Conserva la CTE delivery_feed del starter. Analiza delivered_text, que usa los formatos '%Y-%m-%d', '%m/%d/%Y' y '%b %d, %Y', en delivered_on (un DATE, NULL cuando ningún formato coincide). Haz join con orders y devuelve: order_id, ship_ref (el texto 'ORD-', el order_id, '-', y el mes y día del pedido como '%m%d', p. ej. 'ORD-11500-1031'), order_day (order_date como DATE), delivered_on, days_to_deliver (delivered_on menos order_day, en días) y needs_review (verdadero cuando delivered_on es NULL). Ordena por order_id.

  • Lee de la tabla orderspendiente
  • Muestra exactamente order_id ship_ref order_day delivered_on days_to_deliver needs_reviewpendiente
  • 9 filas, ordenadas como se pidependiente

Tu consulta

SQL

Cargando el editor…

    ResultadoVista previa de orders · presiona Ejecutar para ver el tuyo
    Vista previa de orders
    order_idcustomer_idorder_datestatuschannel
    10011252023-01-01 20:51:19completedweb
    10021562023-01-02 07:58:46completedweb
    1003222023-01-02 10:25:27completedmarketplace
    1004482023-01-02 11:21:51completedmarketplace

    Mote revisa tu resultado

    Presiona Ejecutar. Cada fila que cumple el objetivo se vuelve una luciérnaga en tu linterna.

    Tablas

    Datos de la tienda Harbor & Pine, listos para consultar.

    orders12,000 filas · 7 columnas
    • order_idinteger
    • customer_idinteger
    • order_datetimestamp
    • statusvarchar
    • channelvarchar
    • shipping_feedecimal
    • coupon_codevarchar
    Primeras 5 filas de orders
    order_idcustomer_idorder_datestatuschannelshipping_feecoupon_code
    10011252023-01-01 20:51:19completedweb0.00NULL
    10021562023-01-02 07:58:46completedweb0.00NULL
    1003222023-01-02 10:25:27completedmarketplace4.99WELCOME10
    1004482023-01-02 11:21:51completedmarketplace4.99WELCOME10
    1005822023-01-02 11:43:36completedweb0.00WELCOME10
    customers2,018 filas · 9 columnas
    • customer_idinteger
    • first_namevarchar
    • last_namevarchar
    • emailvarchar
    • cityvarchar
    • statevarchar
    • signup_datedate
    • segmentvarchar
    • referral_sourcevarchar
    Primeras 5 filas de customers
    customer_idfirst_namelast_nameemailcitystatesignup_datesegmentreferral_source
    1OwenHudsonowen.hudson@icloud.comSan FranciscoCA2022-06-02consumersearch
    2DouglasMendozadmendoza69@gmail.comAtlantaGA2022-06-02consumerNULL
    3HenryBrookshbrooks@lakesidecafe.comLos AngelesCA2022-06-04businessNULL
    4BrianGrahambgraham@bluecedarhomes.comSeattleWA2022-06-06businesspinterest
    5KyleJimenezkjimenez27@yahoo.comIndianapolisIN2022-06-07consumerNULL
    products120 filas · 8 columnas
    • product_idinteger
    • namevarchar
    • categoryvarchar
    • subcategoryvarchar
    • unit_pricedecimal
    • unit_costdecimal
    • launched_ondate
    • is_activeboolean
    Primeras 5 filas de products
    product_idnamecategorysubcategoryunit_priceunit_costlaunched_onis_active
    101Vale Velvet LoveseatFurnitureSofas1659.00NULL2023-09-11true
    102Alder Oak Coffee TableFurnitureTables919.00503.502024-05-16true
    103Orchard Rattan Dining ChairFurnitureChairs789.00429.872023-05-27true
    104Upland Oak BookcaseFurnitureStorage429.00214.702022-12-20true
    105Avery Leather Bed FrameFurnitureBeds449.00232.702021-08-31true
    order_items30,338 filas · 6 columnas
    • order_item_idinteger
    • order_idinteger
    • product_idinteger
    • quantityinteger
    • unit_pricedecimal
    • discount_pctdecimal
    Primeras 5 filas de order_items
    order_item_idorder_idproduct_idquantityunit_pricediscount_pct
    11001121931.990.00
    21001154311.990.00
    31002154411.990.00
    410021941149.000.00
    51002193219.990.00
    returns1,673 filas · 5 columnas
    • return_idinteger
    • order_item_idinteger
    • returned_ondate
    • reasonvarchar
    • refund_amountdecimal
    Primeras 5 filas de returns
    return_idorder_item_idreturned_onreasonrefund_amount
    1142023-01-10damaged83.69
    2422023-01-10wrong_item19.99
    31052023-01-14wrong_item10.99
    4242023-01-16changed_mind26.99
    51262023-01-16late20.99
    employees60 filas · 8 columnas
    • employee_idinteger
    • first_namevarchar
    • last_namevarchar
    • departmentvarchar
    • titlevarchar
    • manager_idinteger
    • hire_datedate
    • salaryinteger
    Primeras 5 filas de employees
    employee_idfirst_namelast_namedepartmenttitlemanager_idhire_datesalary
    1CatherineHaleExecutiveChief Executive OfficerNULL2016-03-01285000
    2RobertKimExecutiveChief Operating Officer12017-01-09235000
    3MeganCollinsSalesHead of Sales12018-04-16172000
    4ChloeGutierrezSalesAccount Executive32020-01-2172000
    5FrankBellSalesAccount Executive32023-05-2173000
    web_sessions40,000 filas · 7 columnas
    • session_idinteger
    • customer_idinteger
    • started_attimestamp
    • devicevarchar
    • sourcevarchar
    • pages_viewedinteger
    • convertedboolean
    Primeras 5 filas de web_sessions
    session_idcustomer_idstarted_atdevicesourcepages_viewedconverted
    1NULL2023-01-01 23:02:24mobilepaid1false
    2182023-01-01 15:07:49desktoppaid1false
    3NULL2023-01-01 16:55:46desktopdirect7false
    4NULL2023-01-01 12:43:28mobileorganic3false
    5NULL2023-01-01 13:06:21mobilesocial2false
    marketing_spend3,276 filas · 3 columnas
    • spend_datedate
    • channelvarchar
    • amountdecimal
    Primeras 5 filas de marketing_spend
    spend_datechannelamount
    2023-01-01paid492.99
    2023-01-01email37.38
    2023-01-01social200.53
    2023-01-02paid709.13
    2023-01-02email64.13

    La lección

    Una fecha guardada como texto son solo caracteres. Antes de poder restar, agrupar por mes o comparar, tienes que analizarla, y eso significa decirle a la base de datos qué formato usa el texto.

    strptime y los códigos de formato

    strptime(text, format) lee texto y lo convierte en un TIMESTAMP usando códigos de formato:

    código significa ejemplo
    %Y año de 4 dígitos 2025
    %m número de mes 11 o 3
    %d día del mes 05 o 6
    %b nombre corto del mes Nov
    SELECT strptime('11/05/2025', '%m/%d/%Y');   -- 2025-11-05 00:00:00

    El analizador de DuckDB acepta meses y días de un solo dígito para %m y %d, así que '11/7/2025' también funciona.

    Varios formatos en una columna

    strptime lanza un error cuando el texto no coincide. try_strptime devuelve NULL en su lugar, lo que te permite probar formatos uno tras otro:

    CAST(COALESCE(
      try_strptime(delivered_text, '%Y-%m-%d'),
      try_strptime(delivered_text, '%m/%d/%Y'),
      try_strptime(delivered_text, '%b %d, %Y')
    ) AS DATE) AS delivered_on

    DuckDB también acepta una lista: try_strptime(delivered_text, ['%Y-%m-%d', '%m/%d/%Y']). Lo que siga en NULL después del último formato es tu lista de revisión. En la muestra, el pedido 11500 se hizo en Halloween, 2025-10-31, y se entregó el 2025-11-04: 4 días.

    De fechas de vuelta a texto

    strftime va en el otro sentido, de una fecha a texto en el formato que elijas. Los códigos de referencia suelen incrustar una fecha: CONCAT('ORD-', order_id, '-', strftime(order_date, '%m%d')) da ORD-11500-1031. CONCAT convierte el número en texto por ti.

    Errores comunes

    • Día y mes ambiguos. '05/11/2025' es el 11 de mayo en EE. UU. y el 5 de noviembre en Europa. Ninguna consulta puede saber cuál se quiso decir. Pregunta al remitente su formato y luego analiza cada fuente con su propia regla. '13/11/2025' falla como mes/día, una pista de que este depósito escribe el día primero.
    • Comparar fechas como texto. '11/05/2025' < '2025-11-04' compara caracteres, no fechas.
    • Descartar los fallos. Filtrar las fechas NULL oculta las entregas que más necesitan seguimiento.

    Dialectos y SQL Server

    Postgres y Snowflake usan TO_DATE(text, 'MM/DD/YYYY') (Snowflake también tiene TRY_TO_DATE), BigQuery SAFE.PARSE_DATE('%m/%d/%Y', text), MySQL STR_TO_DATE. SQL Server usa números de estilo: 101 es mm/dd/yyyy, 103 es dd/mm/yyyy, 23 es yyyy-mm-dd. ISDATE y TRY_PARSE ayudan con las comprobaciones.

    SELECT CONCAT('ORD-', o.order_id, '-', FORMAT(o.order_date, 'MMdd')) AS ship_ref,
           COALESCE(TRY_CONVERT(date, f.delivered_text, 23),
                    TRY_CONVERT(date, f.delivered_text, 101)) AS delivered_on
    FROM delivery_feed AS f
    JOIN orders AS o ON o.order_id = f.order_id;

    Elige qué puede ejecutarse en este sitio. Puedes cambiarlo cuando quieras desde "Configurar cookies", al pie de cada página.