Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Firebird e Interbase (https://www.clubdelphi.com/foros/forumdisplay.php?f=19)
-   -   Consulta dinamica (https://www.clubdelphi.com/foros/showthread.php?t=93503)

Angel.Matilla 19-10-2018 11:19:50

Consulta dinamica
 
A ver si soy capaz de explicarme. Tengo una tabla en la que hay, entre otros muchos, estos registros:

Código SQL [-]
GRUPO1 GRUPO2 DATO1 DATO2
93      2      284   6498
95      2       38    456
99      2       90   2185
99      4        1     10
Bien. Necesitaría montar un query para generar un informe de forma que los resultados para cada valor de GRUPO1 aparecieran en la misma línea. Algo así:
Código SQL [-]
GRUPO1 GRUPO2 DATO1 DATO2  ... GRUPOx DATO1x DATO2x
93         2   284   6498
95         2    38    456
99         2    90    2185 ...    4      1      10
(haceros una idea porque no encuentro la forma de encolumnarlos bien :()
He estado probando con CASE...WHEN, con UNION, etc., pero no se me ocurre como montarlo para que me salgan tantas columnas como valores distintos hay en GRUPO2

NOTA (Germán Estévez -Neftalí-): Como truco, si usáis la etiqueta de SQL en lugar de QUOTE, se mantienen los espacios introducidos.

roman 19-10-2018 14:35:16

Cita:

Empezado por Angel.Matilla (Mensaje 529089)
(haceros una idea porque no encuentro la forma de encolumnarlos bien :()

Mira a ver si así es como querías:

Código:

GRUPO1  GRUPO2  DATO1  DATO2
  93      2      284    6498
  95      2        38      456
  99      2        90    2185
  99      4        1      10


Código:

GRUPO1  GRUPO2  DATO1  DATO2  ... GRUPOx  DATO1x  DATO2x
  93      2      284  6498
  95      2      38    456
  99      2      90  2185  ...  4        1      10

Para que quedenn bien alineadas las columnas, escribe todo en un editor de texto y luego encuádralo en etiquetas [code].

// Saludos

Neftali [Germán.Estévez] 19-10-2018 14:46:50

Veo que Román se ha adelantado... o no... ;););)

Angel.Matilla 19-10-2018 18:02:07

Vale... ¡Gracias a los dos! Pero lo de la presentación es el menor de los problemas.:)

Angel.Matilla 19-10-2018 18:44:32

He estado dando vueltas por todos lados (es una forma de hablar ;)) y he encontrado varias respuestas que apuntan en la dirección que quiero ir; casi todas ellas hablan de las CTE. Encontré una sugerencia de fjcg02 que la verdad sea dicha me ha gustado (con un procedimiento) pero tengo que estudiarla a fondo. Antes de implementar nada nuevo he estado probando otra sugerencias que vienen en ese hilo, pero la que más parece aproximarse a mi problema o no estoy desarrollándola bien o no acabo de entenderla.


La tabla tiene, entre otros muchos, estas dos filas:


Estoy usando este código:
Código SQL [-]
WITH Pivote AS (SELECT DISTINCT Estadistica, Grupo1, Grupo2, Grupo3, Dato1 FROM Estadistica)
SELECT A.Grupo1, A.Grupo2, B.Grupo3, B.Dato1, C.Grupo3, C.Dato1
  FROM Estadistica A
  LEFT JOIN Pivote B ON A.Estadistica = B.Estadistica AND A.Grupo1 = B.Grupo1 AND A.Grupo2 = B.Grupo2 AND B.Grupo3 = 3
  LEFT JOIN Pivote C ON A.Estadistica = C.Estadistica AND A.Grupo1 = C.Grupo1 AND A.Grupo2 = C.Grupo2 AND C.Grupo3 = 4
 WHERE SUBSTRING(A.Estadistica FROM 1 FOR 1) = :Estadistica 
  ORDER BY 1, 2
Todos los campos de la tabla son del tipo INTEGER. Al ejecutar esa consulta, entre otras muchas filas, me devuelve esto:


Me devuelve dos filas iguales, y lo hace siempre que para un valor único de la combinación Grupo1-Grupo2 hay más de un posible valor en Grupo3 y es evidente que lo que yo busco es que me devuelva una única fila. ¿alguna sugerencia?

mamcx 19-10-2018 23:59:12

Aqui le pegaste a una de las diferentes limitaciones de SQL. Es pesimo para generar columnas dinamicamente.

Hay una posibilidad y es utilizar LIST:

http://www.developeando.com/2009/02/...-function.html

Casimiro Notevi 20-10-2018 01:23:28

Cita:

Empezado por mamcx (Mensaje 529121)
Aqui le pegaste a una de las diferentes limitaciones de SQL. Es pesimo para generar columnas dinamicamente.
Hay una posibilidad y es utilizar LIST:
http://www.developeando.com/2009/02/...-function.html

Acostumbro a dar un repaso a las cosas nuevas de cada versión y nunca había visto esa función :eek:

Angel.Matilla 20-10-2018 09:55:33

Yo tampoco la conocía. Probaré a ver si me vale, pero no lo tengo muy claro porque por lo que veo genera una lista y me hacen falta columnas separadas para poder generar un informe (que no sé si lo había dicho). No obstante es una función muy interesante. Gracias.

mamcx 20-10-2018 19:55:14

El problema que tienes es que segun veo necesitas crear un numero indeterminado de columnas. No hay como hacer eso hasta donde yo si sin recurrir a stored procedures y programacion manual, generando tablas temporales (luego de hacer lo de LIST y examinar su contenido, luego generar columnas).

Podrias dar mas contexto? Me huele a que hay otro camino pero necesito mas informacion. Como realmente es el informe? Estas son las tablas de entrada? Es posible de predeterminar cuanto es el maximo posible de columnas?

Angel.Matilla 22-10-2018 11:27:10

Vamos a ver. Así lo estoy mostrando ahora en pantalla con un TListView:

Ciñéndome a esta salida:
El número de columnas efectivamente no es fijo; es lo primero que calculo cuando voy a mostrarlo en pantalla para lo que ejecuto este query:
Código SQL [-]
SELECT DISTINCT A.Grupo3, B.Literal
FROM Estadistica A, Instalacion B
WHERE B.Etiqueta = 'Situacion' AND A.Grupo3 = B.Valor
ORDER BY 1, 2
Con este SELECT creo y bautizo las columnas del TListView.

Para rellenarlo uso dos querys. En el primero saco todas las combinaciones distintas Grupo2, Grupo1 y luego, cuando voy poniendo la información en el TListView para cada una de esas combinaciones busco los correspondientes valores de Dato1. Al ser en pantalla no hay ningún problema.

Pero una de las opciones que doy a los usuarios es imprimir ese TListView y, evidentemente, no puedo volcar directamente su contenido en el informe impreso. Por eso estaba buscando como generar ese tipo de querys. Y hacerlo con un stored procedure no me importa, pero el ejemplo que he encontrado no acabo de entederlo.

Angel.Matilla 22-10-2018 12:26:29

Vale. No sé que ha cambiado en la BB.DD. o en el query pero finalmente he conseguido lo que buscaba y creo que el único cambio que he hecho juraría que ya lo había probado. El query ha quedado así:
Código SQL [-]
WITH Pivote AS (SELECT Estadistica, Grupo1, Grupo2, Grupo3, Dato1 
                  FROM Estadistica 
                 WHERE SUBSTRING(Estadistica FROM 1 FOR 1) = :Estadistica)
SELECT DISTINCT A.Grupo1, A.Grupo2, D.Dato1, E.Dato1
  FROM Estadistica A
  LEFT JOIN Pivote D ON A.Estadistica = D.Estadistica AND A.Grupo1 = D.Grupo1 AND A.Grupo2 = D.Grupo2 AND D.Grupo3 = 3
  LEFT JOIN Pivote E ON A.Estadistica = E.Estadistica AND A.Grupo1 = E.Grupo1 AND A.Grupo2 = E.Grupo2 AND E.Grupo3 = 4
 WHERE SUBSTRING(A.Estadistica FROM 1 FOR 1) = :Estadistica  
 ORDER BY 1, 2
Me he llevado fuera el DISTINCT que había enla tabla temporal y ahora si me sale una única fila. Sólo queda mejorarlo ya que la salida no tiene una número fijo de columnas y para eso si que es muy intereante un STORED PROCEDURE.

fjcg02 22-10-2018 23:38:21

Buenas,

tengo entendido, de cuando miré en su día la sentencia WITH , que no acaba de funcionar cuando el nº de columnas varía. Siempre debe ser fijo.

Si en tu caso no es así, no valdría.

Saludos

Angel.Matilla 23-10-2018 09:41:14

Cita:

Empezado por fjcg02 (Mensaje 529175)
tengo entendido, de cuando miré en su día la sentencia WITH , que no acaba de funcionar cuando el nº de columnas varía. Siempre debe ser fijo.

Gracias por contestar. Tal vez me he explciado mal; dentro del WITH el número de columnas va a ser fijo. Lo que varía son los LEFT JOIN, y por lo tanto las columasn de salida, en el SELECT posterior al WITH auqnue siempre será similar al ejemplo con dos salidas para cada LEFT JOIN. El problema que tengo es que los STORED PROCEDURES no los contorlo bien.


La franja horaria es GMT +2. Ahora son las 01:07:35.

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