SQL - Me falta algo y no se que es

 
Vista:
sin imagen de perfil

Me falta algo y no se que es

Publicado por chuko (1 intervención) el 17/10/2017 16:38:12
Buenos dias, tengo un problema y es el siguiente, yo tengo este codigo:

1
2
3
4
5
6
7
8
9
10
11
12
13
create procedure Vdisponibles2 @Finicio date, @Ffin date AS
begin
select *
from Vehiculo
where MLetras   not in(
      select A.MLetras from Alquiler A where (@FFin > FechaInicio) and ( @FInicio < FechaFin ))
   and MDigitos not in(
  select A.MDigitos from Alquiler A where  (@FFin > FechaInicio) and ( @FInicio < FechaFin ))
  end
  go
 
exec Vdisponibles2 '21001010' , '21901212'
go

MLetras y MDigitos son PK de la tabla vehiculos, lo que quiero es que me devuelva que vehiculos hay disponibles entre 2 fechas( osea que no estan alquilados) fecha inicio y fecha fin son de la tabla alquiler, el problema, es que mi profesora nos dice que MLetras y MDigitos no deberian ir por separado, porque ambas juntas son un dato unico, pero no quiere darnos mas ayuda que esa, estamos hace dos dias buscandole la vuelta y no podemos dar con lo que tenemos que modificar, agradeceria si alguien me diera una mano con eso, desde ya muchas gracias!
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
sin imagen de perfil
Val: 806
Bronce
Ha mantenido su posición en SQL (en relación al último mes)
Gráfica de SQL

Me falta algo y no se que es

Publicado por leonardo_josue (1175 intervenciones) el 17/10/2017 18:09:32
Hola Chuko:

Se entiendo bien a lo que se refiere tu maestra es a que no debes hacer dos comparaciones tipo IN, una para el campo MLetras y otro para el campo MDigitos, sino que ambos deben estar en la misma condicion, ya que forman parte de la misma llave. No nos pones datos de ejemplo, pero voy a tratar de explicarlo de otra forma:

Imagina que tienes esta tabla;

1
2
3
4
5
6
7
8
9
10
11
12
mysql> select * from tabla;
+------+-------------+
| id   | descripcion |
+------+-------------+
|    1 | uno         |
|    1 | one         |
|    1 | un          |
|    2 | dos         |
|    2 | two         |
|    2 | deux        |
+------+-------------+
6 rows in set (0.00 sec)

Ahora, ambos datos (ID y descripcion) forman una llave compuesta. si quisieras obtener el número 2 con su descripción en inglés, siguiendo tu lógica de utilizar dos condiciones IN, lo harías así:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
mysql> SELECT id
    -> FROM tabla
    -> WHERE id = 2;
+------+
| id   |
+------+
|    2 |
|    2 |
|    2 |
+------+
3 rows in set (0.00 sec)
 
mysql> SELECT descripcion
    -> FROM tabla
    -> WHERE descripcion = 'two';
+-------------+
| descripcion |
+-------------+
| two         |
+-------------+
1 row in set (0.00 sec)
 
mysql> SELECT *
    -> FROM tabla
    -> WHERE
    ->   id IN ( SELECT id
    ->           FROM tabla
    ->           WHERE id = 2) AND
    ->   descripcion IN ( SELECT descripcion
    ->                    FROM tabla
    ->                    WHERE descripcion = 'two');
+------+-------------+
| id   | descripcion |
+------+-------------+
|    2 | two         |
+------+-------------+
1 row in set (0.00 sec)

Sin embago, esta no es la mejor forma de hacerlo, pues es la combinación de los dos campos lo que te da la unicidad, entonces DEBES COMPARAR AMBOS CAMPOS AL MISMO TIEMPO, en otras palabras filtrar con una subconsulta así:

1
2
3
4
5
6
7
8
9
10
11
mysql> select id, descripcion
    -> from tabla
    -> where
    ->   id = 2 and
    ->   descripcion = 'two';
+------+-------------+
| id   | descripcion |
+------+-------------+
|    2 | two         |
+------+-------------+
1 row in set (0.00 sec)

El problema es que las sentencias IN sólo comparan un campo a la vez... para poder comparar DOS O MAS CAMPOS, lo que haces es utilizar una sentencia EXISTS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mysql> SELECT *
    -> FROM tabla T1
    -> WHERE EXISTS( SELECT id, descripcion
    ->               FROM tabla T2
    ->               WHERE
    ->                 T2.id = 2 AND
    ->                 T2.descripcion = 'two' AND
    ->                 T2.id = T1.id AND
    ->                 T2.descripcion = T1.descripcion);
+------+-------------+
| id   | descripcion |
+------+-------------+
|    2 | two         |
+------+-------------+
1 row in set (0.00 sec)

Es decir, sólo utilizas una subconsulta y ahí puedes poner TODAS LAS CONDICIONES QUE SE DEBEN CUMPLIR PARA QUE EL FILTRADO SEA CORRECTO.

¿Que ventajas tiene esto? pues que es más eficiente, ya que las sentencias IN son las mas lentas en cuanto a performance.

Haz la prueba adecuándolo a tus datos y pregúntale a tu maestra si es esto a lo que se refería y nos comentas.

Saludos
Leo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar