PDA

Ver la Versión Completa : Como hacer un distinct con un group by?


NSL94
18-07-2007, 10:27:24
Bueno dias,
Trabajando con un motor PARADOX tengo la siguiente duda:

Partiendo de esta consulta:

Código SQL [-] (http://www.clubdelphi.com/foros/#)
SELECT
FRA.CLIENTE, EMP.NOMBRE, TEL.TELEFONO, SUM(FRA.BASE_IMP)
FROM
":DBFACTU2:FAC_EMI.DB" AS FRA,
":DBFICHEROS:EMPRESAS.DB" AS EMP,
":DBFICHEROS:TELS_EMP.DB" AS TEL
WHERE
TEL.EMPRESA = EMP.ID_EMPRESA AND
EMP.ID_EMPRESA = FRA.CLIENTE AND
FRA.BASE_IMP <> 0 AND
FRA.CLIENTE IS UNIQUE
GROUP BY
FRA.CLIENTE, EMP.NOMBRE, TEL.TELEFONO
ORDER BY
FRA.CLIENTE





Me encuentro en que que 1-empresa=N-Numeros de telefono.
Pues bien solo quiero que me saque un registro de empresa (solo 1 numero de telefono por empresa) entiendo que para lograrlo deberia usar un distinct en el campo id empresa o nombre empresa, pero al tener un group by me falla la consulta.
Como podria hacer para que no se me repitan las empresas x numeros de telefonos asociados a ella? Es decir que solo salga una vez cada empresa aunque tenga varios num de tel.
Gracias.

NSL94
18-07-2007, 11:20:07
RETIFICO:
El distinct por lo visto no me permite hacer esto aunque no haya agrupaciones, y ademas no me peta con el grup by... tan solo estaba mal escrito. -_-'
Pero me sigue faltando una manera de decirle que tan solo me saque una linea por empresas, es decir que no me saque 3 veces la suma si la empresa x tiene 3 numeros de telefono asociados.

kuan-yiu
18-07-2007, 12:04:54
Tienes que sacar el nº de teléfono del group by, ¿o necesitas un nº de teléfono en concreto?

NSL94
18-07-2007, 12:24:47
si saco el num de telefono del group by no me permite hacer la suma.
:S

fjcg02
18-07-2007, 12:52:10
Puedes quitar el nº de telefono de la consulta, así como la tabla de nº de telefono.

Si necesitas el telefono, ponlo con first( numtelefono) ó last(numtelefono) y quitalo del group by. El problema que puedes encontrar es que ni el primero ni el ultimo telefono que tengas de cada empresa sea el que necesitas.

Prueba y comentanos.

Saludos

NSL94
18-07-2007, 13:09:34
Me es necesario el numero de telefono.
no me funcciona poniendo ni first(tel) ni last(tel) con o sin el tel dentro del grup by.
he intentado probar variaqs combinaciones con el first last etc, pero tan siquiera esto me funcciona.


SELECT
first(TEL.TELEFONO)
FROM
":DBFICHEROS:TELS_EMP.DB" AS TEL


me da error.
Puede venir por el echo de usar paradox??? Lo digo pq ya me he encontrado muchisimas limitaciones, como no poder poner un select dentro de un from o no poder poner condiciones en los group by.
Gracias por vuestros esfuerzos :)

fjcg02
18-07-2007, 13:17:47
No, el problema es de la sentencia que escribes, que está sintácticamente mal.
En una sentencia SQL con agrupaciones, todo lo que no esté en funciones de grupo, de estar incluido en el group by.

Observa que lo he quitado del group by, y le he añadido el first

SELECT
FRA.CLIENTE, EMP.NOMBRE, FIRST(TEL.TELEFONO), SUM(FRA.BASE_IMP)
FROM
"BFACTU2:FAC_EMI.DB" AS FRA,
"BFICHEROS:EMPRESAS.DB" AS EMP,
"BFICHEROS:TELS_EMP.DB" AS TEL
WHERE
TEL.EMPRESA = EMP.ID_EMPRESA AND
EMP.ID_EMPRESA = FRA.CLIENTE AND
FRA.BASE_IMP <> 0
GROUP BY
FRA.CLIENTE, EMP.NOMBRE
ORDER BY
FRA.CLIENTE

En la ultima query que pones , no incluyes ningun group by, por lo que te casca.


Saludos

NSL94
18-07-2007, 13:28:11
Te decia:
"no me funcciona poniendo ni first(tel) ni last(tel) con o sin el tel dentro del grup by" ^^
es decir que probe de ponerlo con o sin el tel en el group by, con o sin group by incluso, pero me de error (Y no, si no pongo el first no me da error)

por ejemplo esta sentencia simplificada tmb me falla y segun lo que tu me escribes entiendo que eso SI deberia funccionar no?



Código SQL [-] (http://www.clubdelphi.com/foros/#)
SELECT
FRA.CLIENTE, EMP.NOMBRE, FIRST(TEL.TELEFONO)
FROM
": DBFACTU2:FAC_EMI.DB" AS FRA,
": DBFICHEROS:EMPRESAS.DB" AS EMP,
": DBFICHEROS:TELS_EMP.DB" AS TEL
WHERE
TEL.EMPRESA = EMP.ID_EMPRESA AND
EMP.ID_EMPRESA = FRA.CLIENTE
GROUP BY
FRA.CLIENTE, EMP.NOMBRE
ORDER BY
FRA.CLIENTE








pongo espacios entre ": DB... para que no salgan los :D :-D

Yo creo que debe de venir con una incompatibilidad de mi paradox con el first... o algo :S ya te digo muchas veces man dado suluciones que no he podido aplicar, por lo visto esto es MUY reducido -_-'

fjcg02
18-07-2007, 13:40:53
Efectivamente, parece que paradox no permite hacer lo que quieres :(

Esta sentencia en cualquier otro motor debiera funcionar sin problemas.

No se me ocurre ninguna solución que no pase por hacer varias querys que 'monten' la información que necesitas.

Suerte y saludos

kuan-yiu
18-07-2007, 16:17:03
Si te da igual qué nº de teléfono sacar prueba con MAX(), esa función debería existir en Paradox.

NSL94
19-07-2007, 09:34:01
Gracias por la propuesta Kuan, debo reconopcer que cuando lei tus lineas pense "Que idiota soy!!! es que alli esta, en las cosas sencillas esta la clave"
Pero NO.

Al usar el MAX( ) me encuentro que se me suman entre ellos los diferentes registros es decir, si 1-empresa tiene N-telefonos la suma sera igual a (SUMA x N) y a mi me interesa sacar la suma X 1 para cada empresa indepedentiemente del numero de telefono que esta tenga, lo que me da igual es que numero sale (si lo se... la sql esta es un poco absurda... pero a mi me mandan por hacer cosas absurdas aqui xDD)
Sigo investigando -_-'

kuan-yiu
19-07-2007, 10:34:57
A ver, que me explico mejor: utiliza MAX() para el teléfono, sólo para el teléfono. Porque se supone que la consulta hace lo que quieres salvo por ese detalle, ¿no?

SELECT
FRA.CLIENTE, EMP.NOMBRE, MAX(TEL.TELEFONO), SUM(FRA.BASE_IMP)
FROM
": DBFACTU2:FAC_EMI.DB" AS FRA,
": DBFICHEROS:EMPRESAS.DB" AS EMP,
": DBFICHEROS:TELS_EMP.DB" AS TEL
WHERE
TEL.EMPRESA = EMP.ID_EMPRESA AND
EMP.ID_EMPRESA = FRA.CLIENTE AND
FRA.BASE_IMP <> 0 AND
FRA.CLIENTE IS UNIQUE
GROUP BY
FRA.CLIENTE, EMP.NOMBRE
ORDER BY
FRA.CLIENTE

Si esto tampo vale creo que necesitaré que me expliques de nuevo que es lo que quieres y cual es la estructura de tus tablas para construir una consulta anidada.

NSL94
19-07-2007, 12:30:39
HAHAHAHA ESO ES UN ROMPECAZAS ^^ ME INCANTA!

En esta consulta que me das tu me encuentro el problema de no poder utilizar el 'IS UNIQUE' sino no habria existido tan siquiera este hilo de discusion :P, debe de ser otra de las muchisimas cosas que no se traga el paradox -_-'.
Con lo cual lo mas parecido que puedo hacer es esto:


SELECT
FRA.CLIENTE, EMP.NOMBRE, MAX(TEL.TELEFONO), SUM(FRA.BASE_IMP)
FROM
": DBFACTU2:FAC_EMI.DB" AS FRA,
": DBFICHEROS:EMPRESAS.DB" AS EMP,
": DBFICHEROS:TELS_EMP.DB" AS TEL
WHERE
TEL.EMPRESA = EMP.ID_EMPRESA AND
EMP.ID_EMPRESA = FRA.CLIENTE
GROUP BY
FRA.CLIENTE, EMP.NOMBRE
ORDER BY
FRA.CLIENTE


Pero haciendo esto el probelma que me encuentro es que si una empresa tiene 2 numeros de telefono tan solo me saca una linea (la del del MAX(TEL) pero me saca la SUM( )x2 -_-'

Entonces mi pregunta es partiendo de esta consulta:


SELECT
FRA.CLIENTE, EMP.NOMBRE, TEL.TELEFONO, SUM(FRA.BASE_IMP)
FROM
": DBFACTU2:FAC_EMI.DB" AS FRA,
": DBFICHEROS:EMPRESAS.DB" AS EMP,
": DBFICHEROS:TELS_EMP.DB" AS TEL
WHERE
TEL.EMPRESA = EMP.ID_EMPRESA AND
EMP.ID_EMPRESA = FRA.CLIENTE
GROUP BY
FRA.CLIENTE, EMP.NOMBRE, TEL.TELEFONO
ORDER BY
FRA.CLIENTE


Que como veras me saca para cada empresa un numero de linea = al de numeros de telefonos tiene ligada la empresa y cada linea de la misma empresa con la misma suma (ya que es un sum de un campo). Es decir una empresa que tenga 4 numeros de telefonos saca 4 lines identicas salvo el campo del numero de telefono.
Lo que me interesa es que tan solo me salga una de estas lineas, pero con la suma NO multiplicada por el numero de telefono, sino tal y como me sale en mi consulta. Es decir para una empresa de 4 telefonos (como en el caso anterior) cargarme, a saco, digase borar, 3 de las lineas y quedarme tan solo con una de ellas.
Esto se podria, entiendo yo, resolver con el IsUnique sobre el id del cliente (FRA.CLIENTE) pero el caso es que mi paradox no se lo traga.
Otras herramientas que NO puedo usar:
-Poner condiciones en el group by
-poner un select en un From
-ni el First( ), Ni el Last( )
-ni el Is UNIQUE
etc...

en fin espero que esto te aclare un pokito mas el caso.

NSL94
19-07-2007, 12:32:34
tampoco puedo sacar el Tel del group by teniendo el sum.

kuan-yiu
19-07-2007, 13:50:34
¿Qué hace exactamente el "is unique"? No conozco esa sentencia.
A ver, la consulta se puede hacer en dos fases, un momento que lo compruebo antes en Oracle (adaptándola claro está) y ahora te la pongo.

kuan-yiu
19-07-2007, 13:57:42
A ver si no me he liado al pasarlo a Paradox... Creo que quedaría algo así:
select q1.cliente,q1.nombre,max(tel.telefono),q1.base_imp
from
": DBFICHEROS:TELS_EMP.DB" AS TEL,
(SELECT FRA.CLIENTE, EMP.NOMBRE, SUM(FRA.BASE_IMP)
FROM ": DBFACTU2:FAC_EMI.DB" AS FRA,
": DBFICHEROS:EMPRESAS.DB" AS EMP
WHERE EMP.ID_EMPRESA = FRA.CLIENTE
GROUP BY FRA.CLIENTE, EMP.NOMBRE, TEL.TELEFONO) as q1
where
TEL.EMPRESA = EMP.ID_EMPRESA
ORDER BY
CLIENTE

NSL94
19-07-2007, 15:22:53
me preguntas que es el is unique? -_-¡ yo no puedo usarlo en mi paradox, pero por el nombre me lo supongo xDD ara bien el codigo que me proponias tu era:

SELECT
FRA.CLIENTE, EMP.NOMBRE, MAX(TEL.TELEFONO), SUM(FRA.BASE_IMP)
FROM
": DBFACTU2:FAC_EMI.DB" AS FRA,
": DBFICHEROS:EMPRESAS.DB" AS EMP,
": DBFICHEROS:TELS_EMP.DB" AS TEL
WHERE
TEL.EMPRESA = EMP.ID_EMPRESA AND
EMP.ID_EMPRESA = FRA.CLIENTE AND
FRA.BASE_IMP <> 0 AND
FRA.CLIENTE IS UNIQUE
GROUP BY
FRA.CLIENTE, EMP.NOMBRE
ORDER BY
FRA.CLIENTE


xDD

En fin la ultima propuesta tampoco me sirve, ya que no puedo poner un select dentro de un from -_-¡
No se si hay versiones de paradox pero el soft es del 95-96... imaginate.

kuan-yiu
19-07-2007, 16:07:38
Lo siento, me he perdido. He utilizado tu primera consulta basándome en que era esa la que funionaba parcialmente.
Pon la estructura de las pablas implicadas, sus índices y con un ejemplo que es lo que quieres obtener.

NSL94
19-07-2007, 16:39:22
partiendo de esta consulta:


SELECT
FRA.CLIENTE, EMP.NOMBRE, TEL.TELEFONO, SUM(FRA.BASE_IMP)
FROM
": DBFACTU2:FAC_EMI.DB" AS FRA,
": DBFICHEROS:EMPRESAS.DB" AS EMP,
": DBFICHEROS:TELS_EMP.DB" AS TEL
WHERE
TEL.EMPRESA = EMP.ID_EMPRESA AND
EMP.ID_EMPRESA = FRA.CLIENTE
GROUP BY
FRA.CLIENTE, EMP.NOMBRE, TEL.TELEFONO
ORDER BY
FRA.CLIENTE


Esta consulta me funcciona(NO DA ERRORES), pero no como quisiera.

LO QUE QUIERO HACER:
Sacar un listado de empresas con codigo, nombre, una suma de todos los campos Base_Imp de los albaranes liados a esta empresa y por ultimo un numero de telefono liado a esta empresa, uno y solo uno.
EL PROBLEMA (LO QUE HACE ESTA CONSULTA ver arriba):
Cuando una empresa tiene varios numeros de telefono, me sale un registro por cada empresa, cada uno de estos registros tiene la suma.
Lo que provoca que el sumario del report (La suma final de las sumas) es erona.

EJEMPLO:
empresa 1 tiene 3 numeros de telefono
empresa 2 tiene 1 numero de telefono

LO QUE SACO YO (ERONEO)
cod \ nombre \ suma \ telefono
001 \ empresa1 \ 100 \ 930000
001 \ empresa1 \ 100 \ 930001
001 \ empresa1 \ 100 \ 930002
002 \ empresa2 \ 105 \ 931111
sumario: 405 ->totalmente falso!

LO QUE QUIERO SACAR:
001 \ empresa1 \ 100 \ el numero que sea, me da igual el que salga.
002 \ empresa2 \ 105 \ 931111
sumario: 205 -> suma final corecta.

te recuerdo que no puedo usar ni last ni first, ni condiciones en el group by ni tampoco selects en el from.

fjcg02
19-07-2007, 23:43:27
Tras hacer unas pruebas, me he dado cuenta de que el problema está en el modelo de datos. Tal como lo tienes, no podrás sacar la información que quieres creo - aunque puedo equivocarme , cuidado - que en ningun motor de BBDD. :confused:

La solución que propongo, suponiendo que harás esta consulta para presentar los datos en un grd o en un informe:
1.-Hacer una consulta de las tablas empresas y facturas. Esta sí te saca la información que necesitas de Empresa y suma de facturas.
2.- Añadir a la consulta del punto anterior un campo calculado en que calcules con otra query el nº de telefono que quieras de los que tenga cada empresa.

Suerte y saludos ;)