Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   SQL (https://www.clubdelphi.com/foros/forumdisplay.php?f=6)
-   -   Cómo NO usar Group By... (https://www.clubdelphi.com/foros/showthread.php?t=70927)

Walterio 19-11-2010 19:38:14

Cómo NO usar Group By...
 
Hola amigos...
Tengo una duda un poco elemental tal vez, pero no logro dar con el resultado.
Utilizo Firebird 2.1 con Delphi 7.1.
Tengo la siguiente consulta :
Código SQL [-]
SELECT STOCK_EXP.ARTICULO, STOCK_EXP.NRO_CAJA, SUM(STOCK_EXP.CANTIDAD) AS TOTAL
  FROM STOCK_EXP
  GROUP BY STOCK_EXP.ARTICULO, STOCK_EXP.NRO_CAJA HAVING (SUM(STOCK_EXP.CANTIDAD) >= 1)
  ORDER BY STOCK_EXP.ARTICULO, STOCK_EXP.NRO_CAJA

El tema es que si bien, los resultados de las sumas son correctas, lo que muestra en detalle no es lo que dice la suma, porque por, ejemplo, hay un registro que es exactamente igual, por lo tanto, me lo agrupa y me muestra uno sólo, aunque en la suma lo toma correctamente.Entonces, lo que necesito es poder "disfrazar" uno de los campos para que no los tenga que incluir en el Group By y que asi me muestre todos los registros solicitados...¿alguna idea...?

Desde ya, muchas gracias.

Walterio.

Walterio 19-11-2010 19:40:40

Pido disculpas, pero quise poner el código como se debe, entre las etiquetas (la vista previa me lo mostró bién) pero al enviar la pregunta me encuentro que hizo cualquier cosa con el texto puesto entre los tags.

Gracias.

duilioisola 19-11-2010 21:12:15

No entiendo tu pregunda.
He reescrito tu SQL utilizando un alias ( S ) para que sea más legible
Código SQL [-]
SELECT S.ARTICULO, S.NRO_CAJA, SUM(S.CANTIDAD) AS TOTAL 
FROM STOCK_EXP S
GROUP BY S.ARTICULO, S.NRO_CAJA 
HAVING (SUM(S.CANTIDAD) >= 1) 
ORDER BY S.ARTICULO, S.NRO_CAJA
Si tienes
Código:

ARTICULO    NRO_CAJA    CANTIDAD
A            1              5
A            1              2
A            2              3
B            1              7

Te devolverá :
Código:

ARTICULO    NRO_CAJA    TOTAL
A            1              7 {agrupó la de 5 y la de 2 unidades}
A            2              3
B            1              7

¿Qué es lo que quieres que no agrupe?

Walterio 30-11-2010 20:14:40

Hola duilioisola...
Gracias por la respuesta y disculpas por responder tarde...
Efectivamente, como dice tu respuesta y tu ejemplo, es eso exactamente lo que hace la consulta :
Código:

ARTICULO    NRO_CAJA    TOTAL
A            1              7 {agrupó la de 5 y la de 2 unidades}
A            2              3
B            1              7

Y, justamente lo que necesito como resultado final, que lo que muestra tu ejemplo, pero sin agrupar nada.
¿Porqué...?, porque la sumatoria del total será calculado sobre el campo TOTAL, y necesito el detalle, aunque tenga registros duplicados (en todo caso, debo ver por otro lado el porqué de la duplicación de datos, pero ese es otro tema, mas bien operativo), pero ojo, que tal vez esté equivocando los conceptos...me ha pasado en otros casos en que debía "disfrazar" una columna de datos para no tener que incluirla en el GroupBy porque me cambia el resultado final, ¿se entiende...?.
Nuevamente, gracias por la atención.

duilioisola 30-11-2010 20:50:30

Creo que esto podría resolver el problema según creo entenderlo.
Quieres que te salga una columna CANTIDAD y una columna TOTAL
Prueba con este código, creo que te funcionará, aunque no lo he probado (sobre todo no se si funcionará el WHERE)
Básicamente es un select SIN AGRUPAR, porque quieres todos los registros. Se piden los campos y se calcula un último campo como el SUM() de esta misma tabla.

Código SQL [-]
SELECT 
  S.ARTICULO, 
  S.NRO_CAJA, 
  S.CANTIDAD,
  (SELECT SUM(S.CANTIDAD) FROM STOCK_EXP 
   WHERE ARTICULO=S.ARTICULO AND NRO_CAJA=S.NRO_CAJA) AS TOTAL 
FROM STOCK_EXP S
WHERE TOTAL > 1
ORDER BY S.ARTICULO, S.NRO_CAJA

Si tienes
Código:

Código:

ARTICULO    NRO_CAJA    CANTIDAD
A            1              5
A            1              2
A            2              3
B            1              7

Te devolverá :
Código:

Código:

ARTICULO    NRO_CAJA    CANTIDAD          TOTAL
A            1              5              7
A            1              2              7
A            2              3              3
B            1              7              7


Walterio 30-11-2010 21:06:00

Gracias nuevamente duilioisola...
Eso es exactamente lo que quiero hacer, pero no estaba seguro de utilizar un SELECT dentro de otro ya que nunca lo hice y el tema del error de sintaxis me pierde un poco.

Pruebo el código y te cuento.

Desde ya, muchas gracias.

Walterio 01-12-2010 14:55:31

Hola duilioisola...

Probé tu sentencia SQL tal como me la pasaste, pero me da este error :

"Dynamic SQL Error.
SQL error code = -206.
Column unknown.
TOTAL.
At line 8, column 7."

Ahora estoy haciendo pruebas cambiando los órdenes, cambiando los nombres de las columnas y otras cosas...en uno de esos tantos cambios, logré disparar la consulta, pero tardó muchísimo...no llegué a chequear si los resultados eran correctos.
Mas allá de los resultados, me quedó la inquietud de que recursos utilizar cuando debo "disfrazar" cierta columna para no ser alcanzada por el GROUP BY.Recuerdo haber utilizado algún artilugio poco prolijo, pero efectivo en alguna consulta sobre Firebird, pero no sé si es lo correcto.
Nuevamente, gracias por la atención.

Saludos.

duilioisola 01-12-2010 20:56:38

Este select me ha funcionado:
Código SQL [-]
SELECT 
  S.ARTICULO, 
  S.NRO_CAJA, 
  S.CANTIDAD,
  (SELECT SUM(CANTIDAD) FROM STOCK_EXP X
   WHERE X.ARTICULO=S.ARTICULO AND X.NRO_CAJA=S.NRO_CAJA) AS TOTAL
FROM STOCK_EXP S
WHERE (SELECT SUM(CANTIDAD) FROM STOCK_EXP Y
       WHERE Y.ARTICULO=S.ARTICULO AND Y.NRO_CAJA=S.NRO_CAJA) > 1
ORDER BY S.ARTICULO, S.NRO_CAJA

En el anterior había puesto
Código SQL [-]
...(SELECT SUM(S.CANTIDAD) FROM STOCK_EXP...
en donde S era la tabla "exterior" y no la tabla Interior.

¡¡¡IMPORTANTE!!!
Ya que para cada registro del select generas otro select, debes tener en cuenta que serán muchísimos selects.
Es muuuuy importante que tengas buenos índices.
En este caso particular, deberás tener un índice sobre la tabla STOCK_EXP que tenga en cuenta ARTICULO y NRO_CAJA ya que es por estos dos campos por los que filtra el WHERE

Walterio 02-12-2010 14:51:49

Hola duilioisola...

Muchísimas gracias por tu ejemplo...funcionó perfectamente, y además, la sugerencia sobre los índices me resultó de mucha ayuda.
Si bien yo usé muchos índices en otro tipo de tablas, hasta ahora no las usé con base de datos porque mis consultas resultaron rápidas de resolver, pero probando tu código, se había vuelto lento, entonces...creé los indices y...tema solucionado...!!!.
Cuantas cosas tengo para ver con este tema de las bases de datos...!!!.
Nuevamente, mil gracias...!!!.

duilioisola 02-12-2010 15:05:59

Cita:

Cuantas cosas tengo para ver con este tema de las bases de datos...!!!.
Pues si...
En proyectos grandes normalmente está:
- El diseñador de base de datos
- El diseñador gráfico
- El diseñador de interface
- El diseñador de reportes
- El diseñador ...
- Un montón de pringados, llamados comunmente programadores ;)


La franja horaria es GMT +2. Ahora son las 09:30:27.

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