1. Faro

Nivel 2 · Mide la tasa de devolución en SQL

La solicitud

De Angela Rivera, Directora de Atención al Cliente

“Lo acordamos: líneas devueltas sobre líneas vendidas en pedidos completados, por categoría, más el valor de los reembolsos y los motivos. Antes de desglosar nada, muéstrame cómo se reparten las devoluciones entre los estados de pedido, porque sé que los pedidos reembolsados se procesan de forma distinta.”

Tu objetivo

Paso 1 de 3. Revisa dónde están las devoluciones. Para cada línea de pedido, sea cual sea su cantidad, devuelve status, lines (el número de líneas de pedido), returned_lines (líneas con una fila en returns) y return_rate_pct (returned_lines * 100 / lines, redondeado a 1). Ordena por status.

  • Lee de la tabla orderspendiente
  • Lee de la tabla order_itemspendiente
  • Muestra exactamente status lines returned_lines return_rate_pctpendiente

Paso 1 · 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.

    Paso 2 · tu consulta

    SQL

    Cargando el editor…

      ResultadoVista previa de products · presiona Ejecutar para ver el tuyo
      Vista previa de products
      product_idnamecategorysubcategoryunit_price
      101Vale Velvet LoveseatFurnitureSofas1659.00
      102Alder Oak Coffee TableFurnitureTables919.00
      103Orchard Rattan Dining ChairFurnitureChairs789.00
      104Upland Oak BookcaseFurnitureStorage429.00

      Mote revisa tu resultado

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

      Paso 3 · tu consulta

      SQL

      Cargando el editor…

        ResultadoVista previa de products · presiona Ejecutar para ver el tuyo
        Vista previa de products
        product_idnamecategorysubcategoryunit_price
        101Vale Velvet LoveseatFurnitureSofas1659.00
        102Alder Oak Coffee TableFurnitureTables919.00
        103Orchard Rattan Dining ChairFurnitureChairs789.00
        104Upland Oak BookcaseFurnitureStorage429.00

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

        Qué estás revisando, y por qué

        Antes de calcular una tasa, mira a qué pertenecen las devoluciones. Cada fila de devolución apunta a una línea de pedido, y cada línea pertenece a un pedido con un estado. Si las devoluciones se comportan de forma muy distinta según el estado, una sola tasa para todo lo ocultaría.

        Para contar juntas las líneas devueltas y las no devueltas, conserva todas las líneas con un LEFT JOIN:

        FROM order_items AS i
        JOIN orders AS o ON o.order_id = i.order_id
        LEFT JOIN returns AS r ON r.order_item_id = i.order_item_id

        Las líneas sin devolución reciben NULL en todas las columnas de r. COUNT(*) cuenta todas las líneas, COUNT(r.return_id) cuenta solo las devueltas, y su cociente es la tasa de devolución. El resultado del paso 1 muestra los pedidos reembolsados en 96.6% y los completados en 3.3%: dos procesos distintos, y por eso el resto del caso usa solo pedidos completados.

        La tasa y el dinero

        El paso 2 mantiene el mismo JOIN, añade products para la categoría y filtra a pedidos completados y cantidades reales. De una sola consulta salen dos medidas:

        • la tasa de devolución, COUNT(r.return_id) * 100.0 / COUNT(*), que le dice a Atención al Cliente dónde está el trabajo;
        • la proporción de reembolso, SUM(r.refund_amount) * 100.0 / SUM(net revenue), que le dice a Finanzas adónde va el dinero.

        SUM(r.refund_amount) suma solo las líneas devueltas, porque las demás son NULL y SUM las omite. Ambos porcentajes se calculan con totales sin redondear y se redondean al final.

        Motivos como columnas

        El paso 3 parte de returns, ya que solo las líneas devueltas tienen un motivo, y convierte cada motivo en su propia columna con agregación condicional:

        SUM(CASE WHEN r.reason = 'damaged' THEN 1 ELSE 0 END) * 100.0 / COUNT(*) AS damaged_pct

        COUNT(*) aquí son las devoluciones de la propia categoría, así que cada fila suma 100%.

        Cómo leer el resultado

        category return_rate_pct refund_share_pct motivo principal
        Textiles 4.7 5.1 changed_mind 57.9%
        Furniture 4.4 4.7 damaged 46.0%
        Lighting 3.8 4.3 damaged 38.3%
        Kitchen 2.0 2.5 changed_mind 40.6%

        Aparecen dos problemas distintos. Textiles regresa porque los clientes cambian de opinión: el color, el tacto o la talla no son los esperados. Furniture y Lighting regresan rotos. Esos casos necesitan soluciones diferentes.

        Errores comunes

        • Un JOIN interno con returns conserva solo las líneas devueltas y cada tasa se vuelve 100%.
        • COUNT(*) / COUNT(*) entre enteros puede truncar en algunas bases de datos; * 100.0 lo mantiene decimal.
        • Algunos reembolsos por cambio de opinión en Furniture y Outdoor son 15% menores que el valor de la línea: un cargo por reposición. Compara los reembolsos con las ventas, no con los valores de las líneas devueltas, cuando hables del dinero perdido.

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