es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Existe un método mejor en lugar de 2 subconsultas anidadas para esta tarea?

Estoy tratando de escribir el SQL para generar el recuento de usuarios únicos que han comprado el producto B pero nunca han comprado el producto C.

user_id producto fecha de compra
1 A 2015-01-10 00:00:00.000
1 B 2014-11-23 00:00:00.000
1 C 2015-05-01 00:00:00.000
2 A 2014-10-01 00:00:00.000
2 C 2014-12-23 00:00:00.000
3 B 2015-02-15 00:00:00.000
3 D 2014-09-23 00:00:00.000
3 E 2014-06-01 00:00:00.000
4 E 2014-12-14 00:00:00.000
4 F 2015-03-03 00:00:00.000

Tengo una solución, pero es tan fea que apuesto a que hay una manera mejor de hacerlo. ¿Alguna idea sobre cómo mejorar esto en términos de mejores prácticas?

SELECT Count(*) AS compraron_b_sin_c
FROM   (SELECT user_id,
               Sum(compraron_b_sin_c) AS booleano_b_sin_c
        FROM   (SELECT user_id,
                       producto,
                       CASE
                         WHEN producto = 'B' THEN 1
                         WHEN producto = 'C' THEN -1
                         ELSE 0
                       END AS compraron_b_sin_c
                FROM   table_purchases) AS T
        GROUP  BY user_id) AS J
WHERE  booleano_b_sin_c = 1

Estoy editando ya que parece que hay pocas respuestas que tienen operaciones como SUM(producto = ‘C’), pero esto devuelve un error tal como: Error de sintaxis cerca de ‘)’ y marca la fórmula de cierre de paréntesis al lado de la función SUM junto a C.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Aquí hay una posible solución que utiliza subconsultas SQL y el operador NOT EXISTS para contar el número de usuarios únicos que han comprado el producto B pero nunca han comprado el producto C:

    SELECT COUNT(DISTINCT user_id) AS bought_b_no_c
    FROM table_purchases
    WHERE product = 'B'    -- selecciona solo las compras del producto B
      AND NOT EXISTS (     -- excluye las compras del producto C
        SELECT *
        FROM table_purchases
        WHERE user_id = p.user_id AND product = 'C'
      );
    

    Esta consulta primero filtra la tabla de compras para incluir solo las compras del producto B. Luego, utiliza una subconsulta con el operador NOT EXISTS para excluir a cualquier usuario que haya comprado alguna vez el producto C. Finalmente, cuenta el número de user_ids únicos restantes, lo que representa la cantidad de usuarios únicos que han comprado el producto B pero nunca han comprado el producto C.

    Esta solución evita el uso de subconsultas anidadas y expresiones CASE complejas, lo que puede hacer que la consulta sea más legible y más fácil de mantener. También aprovecha el poder del filtrado SQL y los operadores relacionales para expresar la lógica deseada de manera concisa.

Comments are closed.