1. Faro

Nivel 10 · Días sin pedidos en el marketplace

La solicitud

De Ryan Cooper, Gerente Regional de Ventas

“El socio del marketplace dice que nuestro listado se quedó callado algunos días el año pasado. ¿Cuántos días de cada mes de 2025 tuvieron cero pedidos del marketplace? Los días sin pedidos no aparecen en un conteo normal, así que necesito hacerlos visibles.”

Tu objetivo

Genera todos los días de calendario del 2025-01-01 al 2025-12-31 con un CTE recursivo. Cuenta los pedidos del marketplace (channel 'marketplace', cualquier estado) por día de calendario de order_date. Devuelve una fila por mes con: month (primer día del mes, como DATE), days (días de calendario del mes) y zero_days (días sin ningún pedido del marketplace). Ordena por month ascendente.

  • Lee de la tabla orderspendiente
  • Muestra exactamente month days zero_dayspendiente
  • 12 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

    GROUP BY solo puede informar de valores que existen en los datos. Un día sin pedidos no tiene filas, así que nunca aparece. Para verlo, necesitas una lista de todos los días con la que hacer el join: una tabla calendario (calendar spine). Un CTE recursivo puede construirla.

    Cómo funciona WITH RECURSIVE

    WITH RECURSIVE calendar AS (
      SELECT DATE '2025-01-01' AS day          -- anchor: the first row
      UNION ALL
      SELECT CAST(day + INTERVAL 1 DAY AS DATE) -- recursive part: reads the previous rows
      FROM calendar
      WHERE day < DATE '2025-12-31'             -- stop condition
    )
    SELECT COUNT(*) FROM calendar;              -- 365

    El ancla se ejecuta una vez. La parte recursiva se ejecuta entonces una y otra vez sobre las filas producidas por la última ronda, hasta que no produce nada porque la condición del WHERE falla. Si olvidas la condición de parada, la consulta nunca termina, así que escríbela primero.

    El mismo patrón recorre jerarquías. Partiendo del CEO (el empleado sin gerente) y uniendo repetidamente los empleados cuyo manager_id está en la ronda anterior, obtienes a todos los empleados con su profundidad en el organigrama: Catherine Hale en profundidad 0, y las personas más profundas de Customer Support en profundidad 4.

    Calendario más LEFT JOIN

    Con la tabla calendario lista, agrega los pedidos por día en un segundo CTE y haz LEFT JOIN con el calendario. Los días sin pedidos sobreviven al join con NULL, y COUNT(CASE WHEN d.day IS NULL THEN 1 END) los cuenta. En 2025 el marketplace no tuvo pedidos durante 11 días en febrero y en ninguno en noviembre, cuando el tráfico navideño llenó todos los días.

    DuckDB también tiene un atajo, SELECT * FROM generate_series(DATE '2025-01-01', DATE '2025-12-31', INTERVAL 1 DAY), pero la recursión funciona en casi todas las bases de datos y además maneja árboles, algo que una serie no puede.

    Errores comunes

    • Unir por el timestamp: order_date tiene una hora del día, así que conviértelo a DATE antes de hacer coincidir los días.
    • Contar COUNT(d.orders) para los días en cero: eso cuenta los días con pedidos.

    En SQL Server

    Escribe WITH calendar AS (...) sin la palabra RECURSIVE, usa DATEADD(day, 1, day) para avanzar, y ten en cuenta el límite por defecto de 100 rondas de recursión. Un año completo necesita OPTION (MAXRECURSION 400) al final de la sentencia, o 0 para no tener límite.

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