Prueba con esto
Código SQL
[-]
SELECT DISTINCT PLAT.linea,PLAT.destino, PLAT.fecha_hora_inicio FROM PLAT
INNER JOIN GUAN ON (PLAT.LINEA=GUAN.CALLINGNUMBER)
WHERE
(PLAT.FECHA_HORA_INICIO BETWEN :F_INICIO AND :F_FIN) AND
( GUAN.CALLTIME BETWEN DATEADD(HOUR,-2,:F_INICIO) AND DATEADD(HOUR,2,:F_FIN)
Te quitas las dos primeras select y una parte de la tercera. Es decir, cruzamos las tablas PLAT y GUAN, con destino iguales, con fecha_hora_inicio entre el rango y con CALLTIME dos horas antes o despues.
Pongo DISTINCT para que sólo me saque un registro por combinación de los tres campos, obviando los duplicados.
Esto tiene que ir rápido, tienes indices en los campos por los que cruzamos.
Ahora nos queda el tema de DESTINO, que si es de longitud mayor que 9 te quedas con el campo menos los 4 ultimos caracteres, y si no, con todos.
Tendrías que probar algo similar a esto
Código SQL
[-]
AND (CASE
WHEN LENGTH(PLAT.DESTINO) > 9
THEN
CASE
WHEN
LEFT(PLAT.DESTINO,LENGTH(PLAT.DESTINO)-4)=LEFT(CALLEDNUMBER,LENGTH(PLAT_DESTINO)-4) THEN
1
ELSE
0
ENDCASE
ELSE
CASE
WHEN
LEFT(PLAT.DESTINO,LENGTH(PLAT.DESTINO))=LEFT(CALLEDNUMBER,LENGTH(PLAT_DESTINO)) THEN
1
ELSE
0
ENDCASE
ENDCASE ) = 1
en las condiciones. No se si tragará, pero es cuestion de probarlo. Si no funciona sería cuestión de ponerlo en un campo calculado, y en la where preguntar por ese campo.
La ultima parte es un poco liosa, pero creo que puede entenderse. No estoy seguro de lo que quieres filtrar, si pones un juego de ensayo, podríamos ayudarte a cambiar la consulta para darle otea orientación.
Un saludo