** NORMAS DEL FORO **
Inicio del foro Inicio del foro > Access y VBA > Access y VBA
  Mensajes nuevos Mensajes nuevos RSS - SQL anidada
  Preguntas frecuentes Preguntas frecuentes  Buscar en el foro   Eventos   Registro Registro  Iniciar sesion Iniciar sesion

Tema cerradoSQL anidada

 Responder Responder Página  12>
Autor
Mensaje
01loko Ver desplegable
Colaborador
Colaborador


Unido: 17/Agosto/2017
Localización: Santander
Estado: Sin conexión
Puntos: 745
Enlace directo a este mensaje Tema: SQL anidada
    Enviado: 01/Marzo/2018 a las 11:19

creo que se llama asi, y es la primera:
Lo que intento es filtrar las viviendas segun unos campos:


 SQL1 = "SELECT TABLA1.Id, TABLA1.JARDIN, TABLA1.GARAJE, TABLA1.ASCENSOR, TABLA1.TERRAZAS, TABLA1.[Tipo vivienda],"
    'SQL1 = SQL1 & "tipoproducto.tipo , tipoproducto.id , TABLA1.ALQUILADO , TABLA1.Zona, TABLA1.[N PLAZAS], TABLA1.DORMITORIOS, TABLA1.REFERENCIA, TABLA1.NOMBRE, TABLA1.DIRECCION, TABLA1.POBLACION,"
    SQL1 = SQL1 & " TABLA1.ALQUILADO , TABLA1.Zona, TABLA1.[N PLAZAS], TABLA1.DORMITORIOS, TABLA1.REFERENCIA,"
    SQL1 = SQL1 & "TABLA1.DESCRIPCION, TABLA1.SITUACION, TABLA1.COCINA, TABLA1.SALONES, TABLA1.BAÑOS, TABLA1.ASEOS, TABLA1.OTROS,"
    SQL1 = SQL1 & "TABLA1.[TIPOS DE CALEFACCION], TABLA1.MASCOTAS, TABLA1.CONFHABITACIONES "
    SQL1 = SQL1 & "FROM TABLA1" 'INNER JOIN tipoproducto ON TABLA1.[Tipo vivienda] = tipoproducto.Id"
    'SQL1 = SQL1 & "FROM tipoproducto INNER JOIN TABLA1 ON tipoproducto.Id = TABLA1.[Tipo vivienda]"
    SQL1 = SQL1 & " WHERE (((TABLA1.ALQUILADO)=False) "
    If Me.JARDIN <> 0 Then SQL1 = SQL1 & "and ((TABLA1.JARDIN)=-1 ) "
    If Me.GARAJE <> 0 Then SQL1 = SQL1 & "and ((TABLA1.GARAJE)=-1) "
    If Me.ASCENSOR <> 0 Then SQL1 = SQL1 & "and((TABLA1.ASCENSOR)=-1) "
    If Me.TERRAZAS <> 0 Then SQL1 = SQL1 & "and((TABLA1.TERRAZAS)=-1) "
    If Me.btipovivienda <> 9 And mebtipovivienda > 0 Then SQL1 = SQL1 & "and((TABLA1.[Tipo vivienda])=" & Me.btipovivienda & ") "
    If Me.bzona = 7 Then SQL1 = SQL1 '& " and ((TABLA1.Zona)= *) "
    If Me.bzona <> 7 Then SQL1 = SQL1 & "and ((TABLA1.Zona)=" & Me.bzona & ") "
    If Me.bplazas >= 1 Then SQL1 = SQL1 & "AND ((TABLA1.[N PLAZAS])>=" & Me.bplazas & ") "
    If Me.bdormitorios >= 1 Then SQL1 = SQL1 & "AND ((TABLA1.DORMITORIOS)>=" & Me.bdormitorios & ") "
    SQL1 = SQL1 & ");"
y de ese resultado filtrarlo entre fechas:
sql2 = "SELECT * FROM " & SQL1 & " INNER JOIN Tabla2 ON  sql1.REFERENCIA = Tabla2.referencia; where fechaicicio >= '" & Format(Me.inicio, "dd/mm/yyyy") & "' and fechafin <= '" & Format(Me.fin, "dd/mm/yyyy") & "';"


pero no avanzo ¿veis donde esta el fallol?

Recordar de que soy nuevo y estoy aprendiendo.
Arriba
pitxiku Ver desplegable
Colaborador
Colaborador
Avatar

Unido: 27/Septiembre/2017
Localización: En mi casa
Estado: Sin conexión
Puntos: 1226
Enlace directo a este mensaje Enviado: 01/Marzo/2018 a las 11:45
A bote pronto:

- No hay espacios entre algún AND y el paréntesis de apertura en los criterios.
- Si usas el asterisco (*) para filtrar, tienes que usar el LIKE, no el igual.
- Puedes agregar la Tabla2 a la sql, y filtrar ahí por las fechas. Lo que no puedes hacer es colocar una SQL detrás del FROM:

 SELECT * FROM SELECT ...

Un consejo: crea la consulta con el diseñador de consultas de Access, aunque sea con valores constantes en vez de los controles. Cuando te funcione, pásala a VBA y ve modificando poco a poco.
Arriba
xavi Ver desplegable
Administrador
Administrador
Avatar
Terrassa-BCN

Unido: 10/Mayo/2005
Localización: Catalunya ||||
Estado: Sin conexión
Puntos: 13015
Enlace directo a este mensaje Enviado: 01/Marzo/2018 a las 13:01
Mas consejos
- En los criterios del WHERE, si todos son AND, puedes ahorrarte casi todos los parentesis.
- Las fechas se delimitan con #
- Las fechas van en formato yankee mm/dd/yyyy
- El ; del final también te lo puedes ahorrar


Un saludo

Xavi, un minyó de Terrassa

Mi web
Arriba
01loko Ver desplegable
Colaborador
Colaborador


Unido: 17/Agosto/2017
Localización: Santander
Estado: Sin conexión
Puntos: 745
Enlace directo a este mensaje Enviado: 01/Marzo/2018 a las 19:45

Despues de crear una consulta y pasarlo a codigo estoy en este punto Cry

Esto es un print sql1 en la ventana de inmediato

SELECT TABLA1.Id, TABLA1.JARDIN, TABLA1.GARAJE, TABLA1.ASCENSOR, TABLA1.TERRAZAS, TABLA1.[Tipo vivienda], TABLA1.ALQUILADO , TABLA1.Zona, TABLA1.[N PLAZAS], TABLA1.DORMITORIOS, TABLA1.REFERENCIA,TABLA1.DESCRIPCION, TABLA1.SITUACION, TABLA1.COCINA, TABLA1.SALONES, TABLA1.BAÑOS, TABLA1.ASEOS, TABLA1.OTROS,TABLA1.[TIPOS DE CALEFACCION], TABLA1.MASCOTAS, TABLA1.CONFHABITACIONES FROM TABLA1 WHERE ((TABLA1.ALQUILADO)=False)  FROM TABLA1 INNER JOIN Tabla2 ON TABLA1.REFERENCIA = Tabla2.referencia WHERE (Tabla2.FechaInicio)>= #'01/01/2018'# AND (Tabla2.FechaFin)<=#'31/12/2018'#;

 

 Me da este error:

Error de sintaxis (falta operador) en la expresión ((tabla1.alquilado)=False) from tabla1 iner join tabla2 and tabla1.referencia=tabla2.referencia where (tabla2.fechainicio) >= #’01/01/2018’# and (tabla2.fechafin) <=#’31/12/2018’#.


edito que me faltaba un parentesis



Editado por 01loko - 01/Marzo/2018 a las 19:46
Recordar de que soy nuevo y estoy aprendiendo.
Arriba
pitxiku Ver desplegable
Colaborador
Colaborador
Avatar

Unido: 27/Septiembre/2017
Localización: En mi casa
Estado: Sin conexión
Puntos: 1226
Enlace directo a este mensaje Enviado: 01/Marzo/2018 a las 20:43
1. Es que no puedes colocar 2 cláusulas FROM en la consulta:

FROM TABLA1 WHERE ((TABLA1.ALQUILADO)=False)  FROM

2. Como dice Xavi, las fechas se delimitan con # (almohadilla), no con #' (almohadilla + comilla):

WHERE (Tabla2.FechaInicio)>= #'01/01/2018'#
AND (Tabla2.FechaFin)<=#'31/12/2018'#
Arriba
Mihura Ver desplegable
Administrador
Administrador
Avatar

Unido: 06/Mayo/2005
Localización: En la dehesa
Estado: Sin conexión
Puntos: 11692
Enlace directo a este mensaje Enviado: 01/Marzo/2018 a las 20:54
where (tabla2.fechainicio) >= #’01/01/2018’# and (tabla2.fechafin) <=#’31/12/2018’#

Formato de fecha yanqui #mm/dd/yyyy# (como te ha dicho Xavi), sin comillas de separador, ... y yo pondría blancos para separar operadores y el símbolo #:

where (tabla2.fechainicio) >= #01/01/2018# and (tabla2.fechafin) <= #12/31/2018#

Por cierto, yo usaría BETWEEN:

WHERE (tabla2.fechainicio) BETWEEN #01/01/2018# AND #12/31/2018#


Jesús Mansilla Castells.
Saludos desde Móstoles.

Access Aplicaciones
Tecsys.es
Arriba
01loko Ver desplegable
Colaborador
Colaborador


Unido: 17/Agosto/2017
Localización: Santander
Estado: Sin conexión
Puntos: 745
Enlace directo a este mensaje Enviado: 01/Marzo/2018 a las 21:04
ya esta solucionado:

SELECT TABLA1.Id, TABLA1.JARDIN, TABLA1.GARAJE, TABLA1.ASCENSOR, TABLA1.TERRAZAS, TABLA1.[Tipo vivienda], TABLA1.ALQUILADO , TABLA1.Zona, TABLA1.[N PLAZAS], TABLA1.DORMITORIOS, TABLA1.REFERENCIA,TABLA1.DESCRIPCION, TABLA1.SITUACION, TABLA1.COCINA, TABLA1.SALONES, TABLA1.BAÑOS, TABLA1.ASEOS, TABLA1.OTROS,TABLA1.[TIPOS DE CALEFACCION], TABLA1.MASCOTAS, TABLA1.CONFHABITACIONES  FROM TABLA1 INNER JOIN Tabla2 ON TABLA1.REFERENCIA = Tabla2.referencia WHERE (((Tabla2.FechaInicio)>=#2/1/2018#)     AND ((Tabla2.FechaFin)<=#2/10/2018#));

estaba empeñado en poner solo elfinal de la consulta sql, cuando he cambiado todo empieza a funcionar.

Gracias.

pero me surge un nuevo problema y no se si tiene solucion:

lo que quiero es lo contrario, los que no estan en la tabla2


Recordar de que soy nuevo y estoy aprendiendo.
Arriba
01loko Ver desplegable
Colaborador
Colaborador


Unido: 17/Agosto/2017
Localización: Santander
Estado: Sin conexión
Puntos: 745
Enlace directo a este mensaje Enviado: 02/Marzo/2018 a las 21:09
He llegado hasta aqui:

inicio = format(me.inicio, "mm/dd/yyyy")
  fin = format(me.fin, "mm/dd/yyyy")
 
 
    sql1 = "select tabla1.id, tabla1.jardin, tabla1.garaje, tabla1.ascensor, tabla1.terrazas, tabla1.[tipo vivienda],"
    'sql1 = sql1 & "tipoproducto.tipo , tipoproducto.id , tabla1.alquilado , tabla1.zona, tabla1.[n plazas], tabla1.dormitorios, tabla1.referencia, tabla1.nombre, tabla1.direccion, tabla1.poblacion,"
    sql1 = sql1 & " tabla1.alquilado , tabla1.zona, tabla1.[n plazas], tabla1.dormitorios, tabla1.referencia,"
    sql1 = sql1 & "tabla1.descripcion, tabla1.situacion, tabla1.cocina, tabla1.salones, tabla1.baños, tabla1.aseos, tabla1.otros,"
    sql1 = sql1 & "tabla1.[tipos de calefaccion], tabla1.mascotas, tabla1.confhabitaciones "
   
   
          sql1 = sql1 & " from tabla1"
         
         
sql1 = sql1 & " inner join tabla2"
sql1 = sql1 & " on tabla1.referencia = tabla2.referencia"
sql1 = sql1 & " where not (((datediff('d',#02/01/2018#,[fechainicio]))>=0) and ((datediff('d', [fechafin],#02/01/2018#))<=0))"
'sql1 = sql1 & " and not  (((datediff('d',#02/28/2018#,[fechainicio]))>=0) and ((datediff('d', [fechafin],#02/28/2018#))<=0))"

Pero no me da los resultados deseados:
1º devuelve las viviendas alquiladas en  otros periodos, varias veces.
2º solo devuelve las viviendas que han estado alquiladas alguna vez (tabla2)


Editado por 01loko - 02/Marzo/2018 a las 21:12
Recordar de que soy nuevo y estoy aprendiendo.
Arriba
01loko Ver desplegable
Colaborador
Colaborador


Unido: 17/Agosto/2017
Localización: Santander
Estado: Sin conexión
Puntos: 745
Enlace directo a este mensaje Enviado: 03/Marzo/2018 a las 10:14
a falta de comentarios, podeis cerrar el hilo
Recordar de que soy nuevo y estoy aprendiendo.
Arriba
pitxiku Ver desplegable
Colaborador
Colaborador
Avatar

Unido: 27/Septiembre/2017
Localización: En mi casa
Estado: Sin conexión
Puntos: 1226
Enlace directo a este mensaje Enviado: 03/Marzo/2018 a las 11:32
Sin saber exactamente qué es lo que necesitas que devuelva la consulta:

- INNER JOIN devuelve los registros que están relacionados en las 2 tablas (en tu caso, Tabla1 y Tabla2).

- Si quieres los registros que están en una tabla pero no están en otra, tienes que usar LEFT JOIN (o RIGHT JOIN). Tal vez te sea útil el asistente de consultas de Access: hay una opción para que cree una consulta de no coincidentes.

- Si necesitas filtrar por un periodo de fechas, usa BETWEEN, tal y como apuntaba Mihura:

[TuCampoDeFecha] BETWEEN #01/01/2018# AND #12/31/2018#

A no ser que sea buscar un periodo de fechas dentro de otro periodo de fechas (saber si el 5 de marzo está ocupada, pudiendo ser que se ocupó del 1 al 10 de marzo). En ese caso, tienes que controlar el inicio y el fin. Revisa esto que tiene Mihura en su web:

- http://www.accessaplicaciones.com/ejemplos.html#m11


Editado por pitxiku - 03/Marzo/2018 a las 11:33
Arriba
01loko Ver desplegable
Colaborador
Colaborador


Unido: 17/Agosto/2017
Localización: Santander
Estado: Sin conexión
Puntos: 745
Enlace directo a este mensaje Enviado: 03/Marzo/2018 a las 16:59
Veamos despacio:
Tengo una tabla (tabla1) donde se guardan los datos de inmuebles en alquiler
Tengo otra tabla donde se guardan los periodos alquilados.
Ambas tablas comparten el campo referencia

Lo que intento es  saber que inmuebles estan libres en un periodo concreto.
Recordar de que soy nuevo y estoy aprendiendo.
Arriba
emiliove Ver desplegable
Moderador
Moderador


Unido: 16/Junio/2009
Localización: Mexico
Estado: Sin conexión
Puntos: 5212
Enlace directo a este mensaje Enviado: 03/Marzo/2018 a las 17:56
Para los que no entendemos sql, por que no pones unos dos o tres registros de cada tabla y lo que quieres obtener. para poder entender que quieres hacer exactamente.

Saludos.
Arriba
pitxiku Ver desplegable
Colaborador
Colaborador
Avatar

Unido: 27/Septiembre/2017
Localización: En mi casa
Estado: Sin conexión
Puntos: 1226
Enlace directo a este mensaje Enviado: 03/Marzo/2018 a las 18:15
Si damos una fecha, podemos usar el BETWEEN "al revés":

[LaFechaDada] BETWEEN [CampoFechaInicioAlquiler] AND [CampoFechaFinAlquiler]

Con lo que sabrás en qué registros no está esa fecha (la casa alquilada). Ojo, que si hay más de 1 registro/alquiler para 1 casa, esta puede aparecer con el alquiler no deseado.

Pero puedes usar el criterio en una subconsulta para saber qué casas están alquiladas, y usar un NOT IN (no las quiero):

SELECT ... FROM Tabla1 INNER JOIN Tabla2 ON Tabla1.referencia = Tabla2,referencia WHERE Tabla1.referencia NOT IN (SELECT T2.referencia FROM Tabla2 AS T2 WHERE [LaFecha] BETWEEN T2.fechainicio AND T2.fechafin);

Si lo prefieres, puedes guardar la subconsulta como consulta y usarla luego en la SQL.

Pero así sólo salen las casas que no han sido alquiladas en esa fecha pero sí en otras. Para las casas que nunca han sido alquiladas, hay que cambiar el tipo de relación:

- INNER JOIN devuelve los registros que tienen relación en las 2 tablas.
- LEFT JOIN devuelve todos los registros de la 1ª tabla, y los que estén relacionados en la 2ª.
- RIGHT JOIN devuelve todos los registros de la 2ª tabla, y los relacionados de la 1ª.

Sabiendo eso, podemos hacer algo así:

SELECT ... FROM Tabla1 LEFT JOIN Tabla2 ON Tabla1.referencia = Tabla2.referencia WHERE Tabla2.referencia IS NULL;

Que viene a decir: de todos los registros de la tabla 1 más los que tengas relacionados en la tabla 2, quiero aquellos en los que el campo referencia de la tabla 2 sea un nulo: que van a ser aquellas casas que no hayan sido alquiladas.

Luego ya es sólo jugar con las 2 consultas, ya sea mediante subconsultas, guardando los distintos pasos, o usando consultas de unión, para conseguir lo que deseas.


Arriba
01loko Ver desplegable
Colaborador
Colaborador


Unido: 17/Agosto/2017
Localización: Santander
Estado: Sin conexión
Puntos: 745
Enlace directo a este mensaje Enviado: 03/Marzo/2018 a las 18:22
FechaInicio FechaFin Motivo NumDias referencia Cliente nombre cli Alquiler entrega pendiente
29/12/2017 29/12/2017 ROVACIAS PORTAL 14 - 2º A 1 2 31 UNO 500,00 200,00 VERDADERO
11/01/2018 11/01/2018 ROVACIAS PORTAL 14 - 2º A 1 2 31
600,00 200,00 VERDADERO
12/01/2018 12/01/2018 CASA 1 0 31 UNO 200,00 100,00 VERDADERO
13/01/2018 13/01/2018 CASA 1 0 9999
600,00 200,00 VERDADERO
16/01/2018 21/01/2018 CASA 6 0 62 DOS 300,00 100,05 VERDADERO
23/01/2018 28/01/2018 ROVACIAS PORTAL 14 - 2º A 6 2 62 DOS 600,00 200,00 VERDADERO
29/01/2018 03/02/2018 CASA 6 0 31 UNO 1.000,35 250,00 VERDADERO
30/01/2018 04/02/2018 ROVACIAS PORTAL 14 - 2º A 6 2 31 UNO 400,00 200,00 VERDADERO
04/02/2018 04/02/2018 Bº DE SANTANA - EL TEJO 1 6 77 TRES 400,00 150,00 VERDADERO
05/02/2018 10/02/2018 CASA 6 0 31 UNO 530,00 210,00 VERDADERO
20/02/2018 24/02/2018 ROVACIAS PORTAL 14 - 2º A 5 2 77 TRES 800,00 300,00 VERDADERO


Editado por 01loko - 03/Marzo/2018 a las 18:24
Recordar de que soy nuevo y estoy aprendiendo.
Arriba
01loko Ver desplegable
Colaborador
Colaborador


Unido: 17/Agosto/2017
Localización: Santander
Estado: Sin conexión
Puntos: 745
Enlace directo a este mensaje Enviado: 03/Marzo/2018 a las 18:25
lo anterior es la tabla2, esta es parte de la tabla1:
Id REFERENCIA DESCRIPCION SITUACION COCINA SALONES BAÑOS ASEOS DORMITORIOS TERRAZAS JARDIN
7 2 DUPLEX CON VISTAS AL MAR ROVACIAS PORTAL 14 - 2º A 1 1 2
3 ######## FALSO
8 3 CASA CON JARDIN EN EL TEJO Bº DE CARA, EL TEJO - VALDALIGA 1 1 2
4 (#, #, XXX, X) FALSO ########
10 4 DUPLEX C/ZONAS COMUNES LA COTERUCA, B10 1 1 2
3(XX,Z,XXX) FALSO ########
11 5 CASA INDEPENDIENTE CON JARDIN EL VALLE, 38 1 2 5
4 (#, X, XX.XX) ######## ########
12 1080 APARTAMENTO EN ROVACIAS ROVACIAS, Nº 22 - Nº 7 - ATICO 1 1 1
1 (Z) FALSO FALSO
14 6 CASA MONTAÑESA REHABILITADA Bº DE SANTANA - EL TEJO 1 1 3 1 4 (XX, XX, XX, # X) FALSO ########
15 37 APTO. EDIF. HOTEL COMILLAS APTO. Nº 66 - COMILLAS 1 1 1
1 (#, +sofá cama) FALSO FALSO
Recordar de que soy nuevo y estoy aprendiendo.
Arriba
 Responder Responder Página  12>
  Compartir tema   

Ir al foro Permisos de foro Ver desplegable