1. Faro

Nivel 1 · Acumulado del año que se reinicia cada enero

¿Es nuevo para ti? Lee primero el concepto: Toda métrica es un nivel de detalle, una ventana y un denominador

La solicitud

De Laura Bennett, Directora de Finanzas

“Para el informe financiero de tres años necesito los ingresos mensuales de enero de 2023 a diciembre de 2025, una columna de acumulado del año que empiece de nuevo cada enero y un total acumulado de por vida al lado.”

Tu objetivo

Usando pedidos completados y líneas con quantity > 0, devuelve una fila por mes para todos los meses de los datos con: month (primer día del mes, como DATE), net_revenue (suma de quantity * unit_price * (1 - discount_pct / 100.0), redondeada a 2), ytd_revenue (total acumulado de los ingresos netos desde enero del mismo año hasta ese mes, redondeado a 2) y cumulative_revenue (total acumulado desde el primer mes de los datos hasta ese mes, redondeado a 2). Ordena por month ascendente.

  • Lee de la tabla orderspendiente
  • Lee de la tabla order_itemspendiente
  • Muestra exactamente month net_revenue ytd_revenue cumulative_revenuependiente

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
    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
    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
    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

    Un total acumulado responde “¿cuánto llevamos?”. Finanzas rara vez quiere “lo que llevamos en toda la historia”, sin embargo. Quiere “lo que llevamos este año”, que empieza en cero cada enero. Eso es una cláusula más.

    Dos totales acumulados, una diferencia

    Ya viste SUM(...) OVER (ORDER BY month) en el capítulo de funciones de ventana: con un ORDER BY dentro de OVER, cada fila suma todas las filas hasta ella misma, incluida. Añade PARTITION BY y la suma se reinicia en cada partición:

    SUM(net_revenue) OVER (PARTITION BY YEAR(month) ORDER BY month) AS ytd_revenue,
    SUM(net_revenue) OVER (ORDER BY month)                          AS cumulative_revenue

    YEAR(month) es 2023, 2024 o 2025, así que las 36 filas mensuales caen en tres ventanas de doce. La partición no tiene que ser una columna de la salida. Cualquier expresión sirve.

    Ejemplo resuelto: el cambio de año

    Con pedidos completados y líneas con cantidad positiva, las filas alrededor de enero de 2024 se ven así:

    month net_revenue ytd_revenue cumulative_revenue
    2023-12-01 241,527.32 1,600,531.40 1,600,531.40
    2024-01-01 109,305.64 109,305.64 1,709,837.04
    2024-02-01 77,546.58 186,852.21 1,787,383.61

    El acumulado del año de diciembre de 2023 es el total completo de 2023. Enero de 2024 empieza de nuevo, mientras la columna de por vida continúa. En diciembre de 2025 el total de por vida es $5,896,296.81 y el acumulado del año 2025 es $2,301,690.14.

    Leer el acumulado del año

    El acumulado del año es más útil frente al mismo punto del año pasado. A finales de junio, 2025 estaba en $1,026,835.51 frente a $789,588.04 de 2024, cerca de un 30% por delante. Ten cuidado al extrapolar medio año a un año completo en Harbor & Pine: noviembre y diciembre por sí solos aportaron el 25% de los ingresos de 2025, así que una tienda que está “a la mitad” en junio no está a la mitad de su cifra anual.

    Primero agrega, luego la ventana

    Las funciones de ventana se ejecutan después de GROUP BY. Suma las líneas de pedido a meses en una CTE y luego ejecuta la ventana sobre 36 filas. Escribir SUM(SUM(...)) OVER (...) en una sola consulta también funciona, pero la CTE es más fácil de leer y de comprobar.

    Errores comunes

    • Particionar por lo que no es. PARTITION BY month da a cada fila su propia ventana, así que el total acumulado es igual al valor mensual.
    • Olvidar el ORDER BY dentro de OVER. SUM(net_revenue) OVER (PARTITION BY YEAR(month)) devuelve el total del año completo en cada fila, no uno acumulado.
    • Huecos en los meses. Un total acumulado sobre un mes sin ventas simplemente se salta ese mes. Aquí todos los meses tienen ventas; con datos dispersos, construye primero un calendario.

    En SQL Server

    No hay DATE_TRUNC antes de SQL Server 2022 (DATETRUNC(month, order_date) en 2022+). Usa DATEFROMPARTS(YEAR(order_date), MONTH(order_date), 1). Añade también un marco explícito: el valor por defecto es RANGE, que es más lento y trata las fechas empatadas como un solo paso.

    SUM(net_revenue) OVER (PARTITION BY YEAR(month) ORDER BY month
                           ROWS UNBOUNDED PRECEDING) AS ytd_revenue

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