1. Faro

Nivel 8 · Depura: enero se ve el doble de grande

La solicitud

De Lauren Hayes, Gerente de Email Marketing

“Mi gráfico de estacionalidad de 2024 y 2025 dice que tuvimos 481 pedidos completados en enero. Finanzas dice que enero de 2025 fue 268. Además solo aparecen 12 barras. Los números se ven raros. ¿Qué tiene mal esta consulta?”

Tu objetivo

Arregla la consulta. Para los pedidos con status 'completed' hechos en 2024 o 2025, devuelve una fila por mes de calendario (24 filas) con: month (el primer día del mes, como DATE), orders y coupon_orders (pedidos con un coupon_code). Ordena por month ascendente.

  • Lee de la tabla orderspendiente
  • Muestra exactamente month orders coupon_orderspendiente
  • 24 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

    Esta consulta se ejecuta, el gráfico se dibuja y todos los números están mal. La pista está en el ticket: 12 barras para un rango de dos años.

    Detectar el error

    EXTRACT(month FROM order_date) devuelve un número de 1 a 12 y nada más. Agrupar por él mete todos los eneros de los datos en un solo grupo. Con 2024 y 2025 en el filtro, la barra de enero es enero de 2024 (213 pedidos completados) más enero de 2025 (268): 481.

    Dos comprobaciones rápidas atrapan este tipo de error:

    1. Conteo de filas. Una serie mensual de dos años tiene 24 filas. Doce significa que se fusionaron los años.
    2. Compara un número con una fuente de confianza. La cifra de enero de 2025 de finanzas no coincidía.

    La solución: truncar, no extraer

    DATE_TRUNC('month', ts) conserva el año y el mes y deja el resto en el inicio del mes:

    SELECT CAST(DATE_TRUNC('month', order_date) AS DATE) AS month,
           COUNT(*) AS orders
    FROM orders
    WHERE status = 'completed'
      AND EXTRACT(month FROM order_date) = 1
    GROUP BY CAST(DATE_TRUNC('month', order_date) AS DATE)
    ORDER BY month;

    Esto devuelve 178, 213 y 268 pedidos completados de enero para 2023, 2024 y 2025. Fíjate en que EXTRACT está bien en la cláusula WHERE aquí: elegir los eneros de todos los años es justo para lo que sirve.

    Una fecha real en la columna del mes también ayuda a quien consuma el resultado. Las herramientas de gráficos colocan las fechas en un eje de tiempo correcto, y un join posterior con otra tabla mensual (gasto de marketing, objetivos) puede coincidir por la fecha directamente en lugar de por un año y un número de mes.

    EXTRACT(month) sí tiene usos legítimos: una vista de estacionalidad que promedia “todos los eneros” a propósito. En ese caso divide entre el número de años y etiqueta el eje como “mes del año”, no como una fecha.

    Errores comunes

    • Agrupar por EXTRACT(year ...) y EXTRACT(month ...) como dos columnas funciona, pero devuelve dos números en lugar de una fecha, algo que los gráficos y los joins manejan peor.
    • Olvidar la conversión: DATE_TRUNC sobre un timestamp devuelve un timestamp como 2025-01-01 00:00:00.

    En SQL Server

    DATETRUNC(month, order_date) existe desde SQL Server 2022. En versiones anteriores usa DATEFROMPARTS(YEAR(order_date), MONTH(order_date), 1). MONTH(order_date) y DATEPART(month, order_date) se comportan como EXTRACT: solo el número del mes.

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