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 24-02-2009
Avatar de salvica
salvica salvica is offline
Miembro
 
Registrado: mar 2004
Ubicación: Albacete (España) ... En un lugar de la Mancha ...
Posts: 304
Poder: 21
salvica Va por buen camino
Question Esta subconsulta puede devolver como máximo un registro

Hola a tod@s, de nuevo por estos lares

Código:
Tabla CONTRATOS
===============
      ID_Clave ------> el identificador del contrato
      ID_Inquilino --> el identificador del inquilino (inquilino.ID_CLAVE)
      ID_Propiedad --> el identificador de la propiedad (propiedad.ID_CLAVE)
      ID_Propietario > el identificador del propietario de la propiedad 

Tabla INQUILINO
===============
      ID_Clave ------> el identificador del inquilino
      ...

Tabla PROPIEDAD
===============
      ID_Clave ------> el identificador de la propiedad
      TIPO ----------> el tipo de propiedad (vivienda, garaje, comercial, etc)
      ...
Se trata de sacar TODOS los INQUILINOS con el tipo de propiedades alquiladas, o en blanco si no tiene ninguna.

Inicialmente habia probado con esto:
Código SQL [-]
SELECT inquilin.ID_CLAVE,
       inquilin.NOMBRE, inquilin.APELLIDO_1, inquilin.APELLIDO_2,
       inquilin.NIF,
       inquilin.TELEFONO_1,
       inquilin.DIRECCION, inquilin.LOCALIDAD,
      (SELECT propieda.TIPO
         FROM contrato, propieda
        WHERE contrato.ID_INQUILI=inquilin.ID_CLAVE
          AND contrato.ID_PROPIED=propieda.ID_CLAVE
      ) AS alquilado
  FROM inquilin
 ORDER BY inquilin.APELLIDO_1, inquilin.APELLIDO_2, inquilin.NOMBRE
pero no vale, ya que puede haber (y de hecho los hay) inquilinos con varias propiedades alquiladas, mensaje de error: Esta subconsulta puede devolver como máximo un registro
Gracias adelantadas
salvica
Responder Con Cita
  #2  
Antiguo 24-02-2009
Avatar de ContraVeneno
ContraVeneno ContraVeneno is offline
Miembro
 
Registrado: may 2005
Ubicación: Torreón, México
Posts: 4.738
Poder: 23
ContraVeneno Va por buen camino
Código SQL [-]
Select A.Campo, B.Campo
From TablaA A
left outer join TablaB B On A.ID = B.ID

eso te regresa todos los registros de A y te muestra las ocurrencias en la tabla B, si no hay ninguna, muestra "NULL"
__________________

Responder Con Cita
  #3  
Antiguo 24-02-2009
Avatar de Kipow
Kipow Kipow is offline
Miembro
 
Registrado: abr 2006
Ubicación: Guatemala
Posts: 329
Poder: 19
Kipow Va por buen camino
Por ahi andaria.

Código SQL [-]
select A.ID_CLAVE AS INQUILINO, C.ID_CLAVE AS PROPIEDAD
FROM (INQUILINO A LEFT OUTER JOIN CONTRATOS B ON A.ID_CLAVE = B.ID_INQUILINO) INNER JOIN PROPIEDAD C ON B.ID_CLAVE = 
C.ID_CLAVE

Ahora bien el problema que te esta dando seguramente es porque estas asignando esos valores luego de la consulta con el INTO. si sabes que puede devolver mas de 1 registro no puedes hacerlo asi. debes hacerlo por medio de un cursor.
Responder Con Cita
  #4  
Antiguo 24-02-2009
Avatar de salvica
salvica salvica is offline
Miembro
 
Registrado: mar 2004
Ubicación: Albacete (España) ... En un lugar de la Mancha ...
Posts: 304
Poder: 21
salvica Va por buen camino
Cita:
Empezado por ContraVeneno Ver Mensaje
Código SQL [-]Select A.Campo, B.Campo From TablaA A left outer join TablaB B On A.ID = B.ID


eso te regresa todos los registros de A y te muestra las ocurrencias en la tabla B, si no hay ninguna, muestra "NULL"
Hola ContraVeneno, gracias por responder, he hecho esto:
Código SQL [-]
         SQL.Add( 'SELECT inquilin.ID_CLAVE,' );
         SQL.Add( '       inquilin.NOMBRE, inquilin.APELLIDO_1, inquilin.APELLIDO_2, inquilin.NIF,' );
         SQL.Add( '       inquilin.TELEFONO_1, inquilin.DIRECCION, inquilin.LOCALIDAD,' );
         SQL.Add( '      (SELECT propieda.TIPO' );
         SQL.Add( '         FROM propieda' );
         SQL.Add( '              LEFT OUTER JOIN contrato' );
         SQL.Add( '                ON contrato.ID_INQUILI=propieda.ID_CLAVE' );
         SQL.Add( '      ) AS alquilado' );
         SQL.Add( '  FROM inquilin' );
         SQL.Add( ' ORDER BY inquilin.APELLIDO_1, inquilin.APELLIDO_2, inquilin.NOMBRE' );
y me sigue dando el mismo error
salvica
Responder Con Cita
  #5  
Antiguo 24-02-2009
Avatar de Kipow
Kipow Kipow is offline
Miembro
 
Registrado: abr 2006
Ubicación: Guatemala
Posts: 329
Poder: 19
Kipow Va por buen camino
ya vi tu problema, el problema esta en la consulta anidada,
Código SQL [-]
 SQL.Add( '      (SELECT propieda.TIPO' );
         SQL.Add( '         FROM propieda' );
         SQL.Add( '              LEFT OUTER JOIN contrato' );
         SQL.Add( '                ON contrato.ID_INQUILI=propieda.ID_CLAVE' );
         SQL.Add( '      ) AS alquilado' );



Porque?, porque esa subconsulta solo debe de devolver un valor y como lo estas haciendo te esta devolviendo en algunos
casos varios valores, proba como te lo coloque yo.

Saludos.
Responder Con Cita
  #6  
Antiguo 24-02-2009
Avatar de salvica
salvica salvica is offline
Miembro
 
Registrado: mar 2004
Ubicación: Albacete (España) ... En un lugar de la Mancha ...
Posts: 304
Poder: 21
salvica Va por buen camino
Cita:
Empezado por Kipow Ver Mensaje
Por ahi andaria.

Código SQL [-]select A.ID_CLAVE AS INQUILINO, C.ID_CLAVE AS PROPIEDAD FROM (INQUILINO A LEFT OUTER JOIN CONTRATOS B ON A.ID_CLAVE = B.ID_INQUILINO) INNER JOIN PROPIEDAD C ON B.ID_CLAVE = C.ID_CLAVE

Hola Kipow, he probado tu consulta y ebtengo el error La expresión de combinación no está admitida

Pensé que era más fácil y no lo puse , utilizo ADO y según "Inner Join" no permite anidar "Left Join" en su interior
Responder Con Cita
  #7  
Antiguo 24-02-2009
Avatar de salvica
salvica salvica is offline
Miembro
 
Registrado: mar 2004
Ubicación: Albacete (España) ... En un lugar de la Mancha ...
Posts: 304
Poder: 21
salvica Va por buen camino
No edito el anterior porque se "descabala" todo

Es al revés un Left Join no admite anidar Inner Join en su interior
Responder Con Cita
  #8  
Antiguo 24-02-2009
Avatar de salvica
salvica salvica is offline
Miembro
 
Registrado: mar 2004
Ubicación: Albacete (España) ... En un lugar de la Mancha ...
Posts: 304
Poder: 21
salvica Va por buen camino
Según eso, lo he puesto así:
Código SQL [-]
         SQL.Add( 'SELECT inquilin.ID_CLAVE,' );
         SQL.Add( '       inquilin.NOMBRE, inquilin.APELLIDO_1, inquilin.APELLIDO_2,' );
         SQL.Add( '       inquilin.NIF,' );
         SQL.Add( '       inquilin.TELEFONO_1, inquilin.DIRECCION, inquilin.LOCALIDAD,' );
         SQL.Add( '       propieda.TIPO' );
         SQL.Add( '  FROM inquilin' );
         SQL.Add( '       INNER JOIN (contrato' );
         SQL.Add( '                   LEFT JOIN propieda' );
         SQL.Add( '                      ON contrato.ID_PROPIED=propieda.ID_CLAVE' );
         SQL.Add( '       ) ON inquilin.ID_CLAVE=contrato.ID_INQUILI' );
         SQL.Add( ' ORDER BY inquilin.APELLIDO_1, inquilin.APELLIDO_2, inquilin.NOMBRE' );
pero no me dá los inquilinos que no tienen propiedades alquiladas (posibles inquilinos a hacerles un contrato)
¿ideas?
salvica
Responder Con Cita
  #9  
Antiguo 24-02-2009
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.734
Poder: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
Creo que la solución es esta:

Cita:
Se trata de sacar TODOS los INQUILINOS con el tipo de propiedades alquiladas, o en blanco si no tiene ninguna.
Código SQL [-]
SELECT inquilino.ID_CLAVE,
       inquilino.NOMBRE, inquilino.APELLIDO_1, inquilino.APELLIDO_2,
       inquilino.NIF,
       inquilino.TELEFONO_1,
       inquilino.DIRECCION, inquilino.LOCALIDAD,propiedad.TIPO
FROM INQUILINO
LEFT JOIN CONTRATOS
on inquilino.ID_Clave=CONTRATOS.ID_Inquilino
LEFT JOIN PROPIEDAD
on CONTRATOS.ID_Propiedad=PROPIEDAD.ID_Clave

WHERE PROPIEDAD.TIPO=:TIPO

ORDER BY inquilino.APELLIDO_1, inquilino.APELLIDO_2, inquilino.NOMBRE

Debes utilizar el LEFT JOIN, pues quieres todo lo que esté en la tabla de la izquierda de la relación, sin importar que haya o no datos en la tabla de la derecha de relación.
Qudaría:
Todos los Inquilinos.
De estos todos sus contratos, si las hubiera.
De estos todas sus propiedades, si las hubiera.

Última edición por duilioisola fecha: 24-02-2009 a las 21:35:03.
Responder Con Cita
  #10  
Antiguo 24-02-2009
Avatar de salvica
salvica salvica is offline
Miembro
 
Registrado: mar 2004
Ubicación: Albacete (España) ... En un lugar de la Mancha ...
Posts: 304
Poder: 21
salvica Va por buen camino
Cita:
Empezado por duilioisola Ver Mensaje
Creo que la solución es esta:
Debes utilizar el LEFT JOIN, pues quieres todo lo que esté en la tabla de la izquierda de la relación, sin importar que haya o no datos en la tabla de la derecha de relación.
Qudaría:
Todos los Inquilinos.
De estos todos sus contratos, si las hubiera.
De estos todas sus propiedades, si las hubiera.
Hola duilioisola, gracias, funciona a la perfección. He tenido que adaptarlo al sql de ado y queda así:
Código SQL [-]
         SQL.Clear;
         SQL.Add( 'SELECT inquilin.ID_CLAVE,' );
         SQL.Add( '       inquilin.NOMBRE, inquilin.APELLIDO_1, inquilin.APELLIDO_2,' );
         SQL.Add( '       inquilin.NIF,' );
         SQL.Add( '       inquilin.TELEFONO_1,' );
         SQL.Add( '       inquilin.DIRECCION, inquilin.LOCALIDAD,' );
         SQL.Add( '       propieda.TIPO' );
         SQL.Add( '  FROM inquilin' );
         SQL.Add( '       LEFT JOIN (contrato' );
         SQL.Add( '                  LEFT JOIN propieda' );
         SQL.Add( '                    ON contrato.ID_PROPIED=propieda.ID_CLAVE' );
         SQL.Add( '       ) ON inquilin.ID_CLAVE=contrato.ID_INQUILI' );
         SQL.Add( ' ORDER BY inquilin.APELLIDO_1, inquilin.APELLIDO_2, inquilin.NOMBRE' );
Por cierto, esto para qué era?
Código SQL [-]
         SQL.Add( ' WHERE propieda.TIPO=:TIPO' );
Gracias a tod@s por la ayuda prestada
Salvica
Responder Con Cita
  #11  
Antiguo 25-02-2009
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.734
Poder: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
Cita:
Se trata de sacar TODOS los INQUILINOS con el tipo de propiedades alquiladas, o en blanco si no tiene ninguna
.
El where es para hacer un filtro. Por lo que explicabas, pensé que querías un tipo determinado de propiedad.
De todos modos, y ahora que lo pienso un poco mejor, si quisieras, por ejemplo solo garages, deberías poner algo así:
Código Delphi [-]
   [...]
   SQL.Add( ' WHERE (propieda.TIPO=:TIPO or propieda.TIPO is null)' );
   SQL.Add( ' ORDER BY inquilin.APELLIDO_1, inquilin.APELLIDO_2, inquilin.NOMBRE' );
   Params.ByName['TIPO'].AsString := 'GARAGE';
   [...]
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
Subconsulta para escojer el ultimo de cada registro? Carlex SQL 14 24-09-2018 21:50:32
Se puede saber quien me está bloqueando un registro? diegolf Conexión con bases de datos 2 02-05-2007 16:56:08
Como obtener subconsulta con un valor maximo alexander66 MS SQL Server 3 16-11-2006 03:38:20
¿Una tabla sólo puede estar unida externamente como máximo a otra tabla ? febito Oracle 0 22-06-2004 18:12:16
IBSQL puede devolver un valor haciendo INSERT? altp SQL 2 04-10-2003 22:09:49


La franja horaria es GMT +2. Ahora son las 21:37:40.


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