Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > SQL
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 03-08-2019
adrall adrall is offline
Miembro
 
Registrado: ene 2007
Posts: 94
Poder: 18
adrall Va por buen camino
SELECT con campos columnados

Es posible hacer una consulta SELECT sobre MySQL que devuelva diversas columnas según el valor de un campo?

Imaginemos que este SELECT

Código SQL [-]
SELECT cliente, mes, sum(cantidad) AS importe FROM compra GROUP BY mes,cliente;

devuelve esta muestra
Código:
+----------+--------+-----------+
| cliente  | mes    | importe   |
+----------+--------+-----------+
| PEPE     | 201901 |  25000    |
| ROSA     | 201901 | 180000    |
| EDU      | 201901 | 128000    |
| JAIME    | 201901 |  20000 	|
| JUAN     | 201902 | 250000 	|
| PEPE     | 201902 |  25000 	|
| ROSA     | 201902 | 180000 	|
| EDU      | 201902 | 128000 	|
| JAIME    | 201902 |  20000 	|
| JUAN     | 201902 | 250000 	|
| PEPE     | 201903 |  25000 	|
| ROSA     | 201903 | 180000 	|
| EDU      | 201903 | 128000 	|
| JAIME    | 201903 |  20000 	|
| JUAN     | 201904 | 250000 	|
| PEPE     | 201904 |  25000 	|
| ROSA     | 201904 | 180000 	|
| EDU      | 201904 | 128000 	|
| JAIME    | 201904 |  20000 	|
| JUAN     | 201904 | 250000 	|
+----------+--------+-----------+
Puedo obtener las cantidades de cada mes por columnas agrupado por clientes de alguna manera, esto es posible ??

Muchas gracias

Última edición por ecfisa fecha: 04-08-2019 a las 00:07:36. Razón: Corregir tabulación de los datos
Responder Con Cita
  #2  
Antiguo 03-08-2019
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.911
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
No se entiende. Da el ejemplo de como deberia quedar.
__________________
El malabarista.
Responder Con Cita
  #3  
Antiguo 04-08-2019
Avatar de oscarac
[oscarac] oscarac is offline
Miembro Premium
 
Registrado: sep 2006
Ubicación: Lima - Perú
Posts: 2.010
Poder: 20
oscarac Va por buen camino
busca la utilizacion de "Pivot"
__________________
Dulce Regalo que Satanas manda para mi.....
Responder Con Cita
  #4  
Antiguo 04-08-2019
adrall adrall is offline
Miembro
 
Registrado: ene 2007
Posts: 94
Poder: 18
adrall Va por buen camino
Deberia quedar asi:

Cita:
+----------+--------+-----------++----------+--------+-----------++----------+--------+-----------++----------+--------+-----------+
| cliente | enero | febrero | marzo | abril | mayo | abril etc. etc.
+----------+--------+-----------++----------+--------+-----------++----------+--------+-----------++----------+--------+-----------+
| PEPE | 5000 | 300 |
| ROSA | 8000 | 0 |
| EDU | 0 | 1230 | etc. etc.
| JAIME | 200 | 0 |
| JUAN | 50000 | 300 |
+----------+--------+-----------++----------+--------+-----------++----------+--------+-----------++----------+--------+-----------+
en cada columna / mes las cantidades que correspondan.

Gracias

Última edición por Casimiro Notevi fecha: 04-08-2019 a las 11:53:42.
Responder Con Cita
  #5  
Antiguo 04-08-2019
adrall adrall is offline
Miembro
 
Registrado: ene 2007
Posts: 94
Poder: 18
adrall Va por buen camino
Cita:
Empezado por oscarac Ver Mensaje
busca la utilizacion de "Pivot"
Investigaré las tablas Pivot, desconocía esta funcionalidad.

Muchas gracias. y saludos
Responder Con Cita
  #6  
Antiguo 05-08-2019
bucanero bucanero is offline
Miembro
 
Registrado: nov 2013
Ubicación: Almería, España
Posts: 208
Poder: 11
bucanero Va camino a la fama
hola a todos

Una forma de poder solucionar tu problema puede ser esta:
Código SQL [-]
select distinct cliente.cliente, 
Ifnull((
  -- ventas enero
  SELECT sum(importe) AS importe
  FROM compra
  WHERE month(fecha) = 1 and year(fecha) = year(now()) AND cliente=cliente.cliente
  GROUP BY cliente, month(fecha)
), 0) as enero, 
Ifnull((
  -- ventas enero
  SELECT sum(importe) AS importe
  FROM compra
  WHERE month(fecha) = 2 and year(fecha) = year(now()) AND cliente=cliente.cliente
  GROUP BY cliente, month(fecha)
), 0) as febrero, 
-- ...,
Ifnull((
  -- ventas enero
  SELECT sum(importe) AS importe
  FROM compra
  WHERE month(fecha) = 12 and year(fecha) = year(now()) AND cliente=cliente.cliente
  GROUP BY cliente, month(fecha)
), 0) as diciembre 
from compra cliente
WHERE year(fecha) = year(now()) AND cliente<>''
GROUP BY cliente

El problema:
que te sale una morcilla de SQL... y a parte puede llegar a ser bastante lenta la ejecución, y cualquier cambio en las subconsultas de los meses tienes que aplicarlas a los doce meses.

Cita:
Empezado por oscarac Ver Mensaje
busca la utilizacion de "Pivot"
En cuanto a "PIVOT", que es la solución perfecta a este problema, es un método que realiza el motor de BBDD de microsoft MsSQL y no se si existe también en algún otro motor de BBDD, pero creo que no existe como tal en MySQL, o por lo menos yo no he encontrado nunca información de como aplicarlo directamente para MySQL. Si es verdad que con procedimientos y tablas en memoria se puede llegar a hacer, pero no es tan trivial como lo hace MsSQL.

Lo que si tiene MySQL y se puede utilizar en este caso es la función GROUP_CONCAT() que puede hacer algo similar, concatena los valores de un determinado campo para varios registros cuando se hace un GROUP BY

El ejemplo para este caso sería este:
Código SQL [-]
SELECT cliente.cliente, GROUP_CONCAT(ifNull(ventas.importe, 0) ORDER BY mes.mes SEPARATOR '\,') as resumen
FROM
  -- genera un registro para cada mes de cada cliente
  ((SELECT DISTINCT month(fecha) AS mes FROM compra) mes,
   (SELECT DISTINCT cliente FROM compra) cliente)
  -- rellena los importes del mes
  LEFT JOIN (
    SELECT cliente, month(fecha) AS mes, sum(importe) AS importe
    FROM compra
    WHERE year(fecha)=year(now()) AND cliente<>''
    GROUP BY cliente, month(fecha)
  ) ventas ON ventas.cliente=cliente.cliente AND ventas.mes=mes.mes
GROUP BY cliente

Ventajas: El SQL es mucho mas corto que el anterior, y a nivel de rendimiento, también es mas rápido.
Desventajas: Los datos de ventas salen todos en el mismo campo, separados por comas. Pero entre comillas es un mal menor, puesto que ya desde delphi es relativamente fácil procesarlos, por ejemplo añadiendo los campos de los meses como campos calculados en el query/tabla e inserta el valor en evento onCalculate
Responder Con Cita
  #7  
Antiguo 05-08-2019
bucanero bucanero is offline
Miembro
 
Registrado: nov 2013
Ubicación: Almería, España
Posts: 208
Poder: 11
bucanero Va camino a la fama
Dandole vueltas al tema de extraer la ventas de cada mes del campo con la lista de valores separados por comas, se puede utilizar algo así:

Código SQL [-]
select cliente,
  cast(substring_index(substring_index(resumen, ',', 1), ',', -1) AS DECIMAL(10,2)) as enero, 
  cast(substring_index(substring_index(resumen, ',', 2), ',', -1) AS DECIMAL(10,2)) as febrero,
  cast(substring_index(substring_index(resumen, ',', 3), ',', -1) AS DECIMAL(10,2)) as marzo,
  cast(substring_index(substring_index(resumen, ',', 4), ',', -1) AS DECIMAL(10,2)) as abril,
  cast(substring_index(substring_index(resumen, ',', 5), ',', -1) AS DECIMAL(10,2)) as mayo,
  cast(substring_index(substring_index(resumen, ',', 6), ',', -1) AS DECIMAL(10,2)) as junio,
  cast(substring_index(substring_index(resumen, ',', 7), ',', -1) AS DECIMAL(10,2)) as julio, 
  cast(substring_index(substring_index(resumen, ',', 8), ',', -1) AS DECIMAL(10,2)) as agosto,
  cast(substring_index(substring_index(resumen, ',', 9), ',', -1) AS DECIMAL(10,2)) as septiembre,
  cast(substring_index(substring_index(resumen, ',', 10), ',', -1) AS DECIMAL(10,2)) as octubre,
  cast(substring_index(substring_index(resumen, ',', 11), ',', -1) AS DECIMAL(10,2)) as noviembre,
  cast(substring_index(substring_index(resumen, ',', 12), ',', -1) AS DECIMAL(10,2)) as diciembre
from (
  -- mismo SQL anterior
  SELECT cliente.cliente, GROUP_CONCAT(ifNull(ventas.importe, 0) ORDER BY mes.mes SEPARATOR '\,') as resumen
  FROM
    -- genera un registro para cada mes de cada cliente
    ((SELECT DISTINCT month(fecha) AS mes FROM compra) mes,
    (SELECT DISTINCT cliente FROM compra) cliente)
    -- rellena los importes del mes
    LEFT JOIN (
      SELECT cliente, month(fecha) AS mes, sum(importe) AS importe
      FROM compra
      WHERE year(fecha)=year(now()) AND cliente<>''
      GROUP BY cliente, month(fecha)
    ) ventas ON ventas.cliente=cliente.cliente AND ventas.mes=mes.mes
  GROUP BY cliente
  --
) dat

y con esto ya si se tiene una tabla con cada venta de un determinado mes en su correspondiente columna del mes
Responder Con Cita
  #8  
Antiguo 05-08-2019
orodriguezca orodriguezca is offline
Miembro
 
Registrado: ene 2009
Posts: 221
Poder: 16
orodriguezca Va por buen camino
Yo probaría la siguiente instrucción:

Código SQL [-]
SELECT 
  cliente, 
  sum(case when mes = 201901 then Cantidad else 0) as Enero,
  sum(case when mes = 201902 then Cantidad else 0) as Febrero,
  sum(case when mes = 201903 then Cantidad else 0) as Marzo,
  sum(case when mes = 201904 then Cantidad else 0) as Abril,    
  sum(case when mes = 201905 then Cantidad else 0) as Mayo,    
  sum(case when mes = 201906 then Cantidad else 0) as Junio,    
  sum(case when mes = 201907 then Cantidad else 0) as Julio,    
  sum(case when mes = 201908 then Cantidad else 0) as Agosto,    
  sum(case when mes = 201909 then Cantidad else 0) as Septiembre,    
  sum(case when mes = 201910 then Cantidad else 0) as Octubre,    
  sum(case when mes = 201911 then Cantidad else 0) as Noviembre,    
  sum(case when mes = 201912 then Cantidad else 0) as Diciembre,    
FROM compra 
GROUP BY cliente, mes;
Responder Con Cita
  #9  
Antiguo 12-08-2019
adrall adrall is offline
Miembro
 
Registrado: ene 2007
Posts: 94
Poder: 18
adrall Va por buen camino
Si esta es la solución que me ha parecido mejor aunque he utilizado if en lugar de case .

También he visto alguna solución para cuando no se conocen previamente los nombre de los campos, como esta:

http://buysql.com/mysql/14-how-to-au...ot-tables.html

Muchas gracias y saludos a todos.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
SELECT con campos calculados y condicionados Angel.Matilla Firebird e Interbase 9 11-05-2019 11:56:14
select count con varios campos aanil SQL 4 17-05-2008 02:37:18
Alinear campos en un select (comboBox). mcalmanovici PHP 3 21-09-2007 06:45:35
un Select max de varios campos Camilo SQL 3 07-09-2007 16:34:15
select que me mueste los campos de una tabla cahosoft Oracle 1 01-10-2004 00:02:54


La franja horaria es GMT +2. Ahora son las 18:32:50.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi