Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   FireMonkey (https://www.clubdelphi.com/foros/forumdisplay.php?f=50)
-   -   Busqueda Selectiva (https://www.clubdelphi.com/foros/showthread.php?t=96197)

giantonti1801 12-04-2023 15:45:39

Busqueda Selectiva
 
hola amigos tengo que realizar una operación compleja a nivel de búsqueda dentro de una base de datos donde el resultado puede cambiar según selecion;
Tengo una tabla SQL SERVER con campos string, la tabla se llama 'ENFERMEDADES' dentro de ella una lista de enfermedades:
Código SQL [-]
id          ENFERMEDADES                                       ID_ENF
----------- -------------------------------------------------- --------------------------------------------------
17          ABSCESO CEREBRAL                                   1
18          ABSCESO PERIANAL                                   2
19          ACCIDENTE CEREBROVASCULAR O ICTUS                  3
20          ACNÉ                                               4
21          ACROMEGALIA                                        5
22          ACÚFENOS O TINNITUS (PITIDOS EN EL OÍDO)           6

el campo ID_ENF esta relacionado con las demás tablas, es decir si yo selecciono el número 1 de "ABSCESO CEREBRAL" y lo busco en la Tablas de síntomas me trae como resultado todos los síntomas de esta enfermedad a su vez el mismo número 1 en la tabla de tratamiento me lleva a los tratamientos indicados para esta enfermedad.
Ahora bien mi problema esta en que al aplicarlo a mi desarrollo tengo que hacer una consulta inversa Ejemplo tengo que buscar primero en la tabla síntomas encontrar los síntomas que se relaciones con la ENFERMEDAD y luego pasar a la tabla tratamiento. Pero tengo varias interrogante donde para ellos consulto el foro para encontrar la mejor opción para este gran Reto: En el from he pensado colocar un LISTVIEW alimentado de la tabla de síntomas donde el usuario pueda seleccionar los síntomas. Claro cuando estaba haciendo esto surgió una gran pregunta que existe una gran infinidad de síntomas relacionado con todas la enfermedades y para hacer las cosas más fácil cree una tabla que se llama GRUPO y allí Agrupe los síntomas por GRUPO ejemplo:
Código SQL [-]
34          CABEZA                                                                                                                                                 1
35          ANAL                                                                                                                                                   2
36          CORAZON                                                                                                                                                3
37          CARA                                                                                                                                                   4
como pueden ver hay un campo que se relaciona con todas las tablas. donde el usuario selecciona una opción en el grupo y esto reduce la búsqueda de los síntomas. hasta este punto podemos decir que funciona, talvez no de la manera perfecta pero inicialmente cumple con alguno resultados.
ahora esto me abre muchas preguntas la cual considero que su experiencia me puede ser de gran ayuda.
1. partiendo de un principio que al momento de registrar el paciente todo inicia con un motivo de consulta ejemplo "DOLOR DE CABEZA, DOLOR ABDOMINAL EN EL FLANCO DERECHO' etc yo quisiera que de alguna forma el sistema genere una primera búsqueda que relacione el motivo de la consulta con la tabla de síntomas (Talvez con palabras clave dentro de toda la cadena de texto "MOTIVO DE CONSULTA") como pudiera hacer eso?
2.si se logra eso se abrirá una serie de resultado relacionado con la tabla de SINTOMAS y sabiendo que mucho síntomas son iguales pero están relacionado a otra enfermedades. yo había pensado que se pudiera hacer es por porcentaje de coincidencia. Ejemplo si el usuario selecciona 3 de los 4 síntomas relacionado con una enfermedad esto debería devolver un porcentaje ejemplo del 80% lo cual es suficiente razón para diagnosticar una posible enfermedad. (Como puedo hacer esto) y si hubiera otra forma de hacerlo y filtrar aun mas el diagnostico me encantaría que pudieran hacérmelo saber talvez con pequeños ejemplos, tomando en cuenta que mi nivel de experiencia y conocimiento el delphi es de 4 de una escala de 1-10. Estoy desarrollando con FMX con delphi 11 y estoy utilizando el componente UNIDAC para sql.

duilioisola 13-04-2023 08:00:39

Una forma de obtener enfermedad a través de síntomas sería construir el SQL de la siguiente manera:
Código SQL [-]
/* Esto funciona en Firebird. No estoy seguro de que SQL Server acepte la sentecia EXISTS() */
select *
from enfermedad e
where
/* Primer sintoma */
(exists(select enfermedad
        from sintoma
        where
        id_enfermedad = e.id and
        id_sintoma = :id_sintoma))   
/* Segundo sintoma */
and
(exists(select enfermedad
        from sintoma
        where
        id_enfermedad = e.id and
        id_sintoma = :id_sintoma))   
/* Tercer sintoma */
[...]

duilioisola 13-04-2023 08:18:54

He hecho una prueba simple y este es el resultado que he obtenido:

Código SQL [-]
CREATE TABLE ENFERMEDAD (
    ID           INTEGER,
    DESCRIPCION  VARCHAR(60)
);
CREATE TABLE SINTOMA (
    ID           INTEGER,
    DESCRIPCION  VARCHAR(60)
);
CREATE TABLE SINTOMA_X_ENFERMEDAD (
    ID             INTEGER,
    ID_ENFERMEDAD  INTEGER,
    ID_SINTOMA     INTEGER
);

/*
Enfermedades que contienen alguno de los sintomas 1 y 3
Ordenadas por cantidad de sintomas encontrados
*/
select e.id, e.descripcion,
       count(sxe.id_sintoma) cantidad_sintomas_encontrados,
       list(s.descripcion) lista_de_sintomas
from enfermedad e
join sintoma_x_enfermedad sxe on e.id = sxe.id_enfermedad
join sintoma s on sxe.id_sintoma = s.id
where
id_sintoma in (1, 3)
group by e.id, e.descripcion
order by 3 desc, 1

ID    DESCRIPCION    CANTIDAD_SINTOMAS_ENCONTRADOS    LISTA_DE_SINTOMAS
-----------------------------------------------------------------------
2     E2             2                                S1,S3
1     E1             1                                S1
3     E3             1                                S1

giantonti1801 13-04-2023 16:00:19

Cita:

Empezado por duilioisola (Mensaje 551126)
He hecho una prueba simple y este es el resultado que he obtenido:

Código SQL [-]
CREATE TABLE ENFERMEDAD (
    ID           INTEGER,
    DESCRIPCION  VARCHAR(60)
);
CREATE TABLE SINTOMA (
    ID           INTEGER,
    DESCRIPCION  VARCHAR(60)
);
CREATE TABLE SINTOMA_X_ENFERMEDAD (
    ID             INTEGER,
    ID_ENFERMEDAD  INTEGER,
    ID_SINTOMA     INTEGER
);

/*
Enfermedades que contienen alguno de los sintomas 1 y 3
Ordenadas por cantidad de sintomas encontrados
*/
select e.id, e.descripcion,
       count(sxe.id_sintoma) cantidad_sintomas_encontrados,
       list(s.descripcion) lista_de_sintomas
from enfermedad e
join sintoma_x_enfermedad sxe on e.id = sxe.id_enfermedad
join sintoma s on sxe.id_sintoma = s.id
where
id_sintoma in (1, 3)
group by e.id, e.descripcion
order by 3 desc, 1

ID    DESCRIPCION    CANTIDAD_SINTOMAS_ENCONTRADOS    LISTA_DE_SINTOMAS
-----------------------------------------------------------------------
2     E2             2                                S1,S3
1     E1             1                                S1
3     E3             1                                S1

gracias por tu respuesta y gracias por la solucion ya lo adapte y estoy mas cerca de lograr el objectivo

Código SQL [-]
select E.id, e.descripcion,
       count(sxe.id_sintoma) cantidad_sintomas_encontrados
       /*list(s.descripcion) lista_de_sintomas*/
from enfermedad e
join sintoma_x_enfermedad sxe on e.id = sxe.id_enfermedad
join sintoma s on sxe.id_sintoma = s.id
where
s.descripcion like '%diarrea%'
group by e.id, e.descripcion
order by 3 desc, 1
Código SQL [-]
id  descripcion  cantidad_sintomas_encontrados
19  ALERGIA ALIMENTARIA  2
14  ALERGIA A LA LECHE  1
15  ALERGIA AL CACAHUETE  1
16  ALERGIA AL HUEVO  1
17  ALERGIA AL PESCADO  1
33  ARTRITIS ENTEROPÁTICAS  1

ahora me surgen algunas interrogantes: partiendo de un principio donde todo comienza por una exploración inicial del paciente como ejemplo: 'Paciente con dificultas respiratoria y presión en el pecho' esto es un ejemplo pero dentro de este texto tendría yo que buscar en cualquiera de sus palabras coincidencia con los síntomas. con el like no lo estoy logrando ya que el busca una sola palabra dentro de esta cadena: habrá alguna forma de hacerlo? o habrá alguna forma de lograr eso funcione? la idea inicial es que con esta cadena de texto se reduzcan la búsqueda y de alguna forma luego podría proporcionar unas series de preguntas a fin de acercarme lo mas que pueda con una posible enfermedad o diagnóstico.

Casimiro Notevi 13-04-2023 18:06:31

Containing.

https://firebird21.wordpress.com/tag/containing/

duilioisola 13-04-2023 19:51:37

El problema es que tiene que estar perfectamente escrito (acentos, espacios, puntuación, etc.) Por suerte con CONTAINING las mayúsculas no importan.
Te pongo un ejemplo:
El texto que escribe de exploración dice "... presion en el pecho".
Este síntoma no está en la lista de síntomas.
Código SQL [-]
/*
SINTOMA
ID   DESCRIPCION
-------------------------------
1    Dificultades respiratorias
2    Presion en pecho
3    Diarrea
*/

select *
from sintoma
where
'El paciente presenta dificultades respiratorias y presion en el pecho.' containing descripcion
                                                             ^^^^
/*
RESULTADO
-------------------------------
ID   DESCRIPCION
1    Dificultades respiratorias
*/

Si buscas por palabras, encontrarás más sintomas de los que menciona la exploración.
Por ejemplo todos estos síntomas tienen la palabra presion.
  • presion en la cabeza
  • presion en el pecho
  • presion alta
  • presion baja

mamcx 13-04-2023 20:05:43

Este tipo de tareas se resuelve mejor con FTS:

https://learn.microsoft.com/en-us/sq...l-server-ver16

giantonti1801 14-04-2023 03:14:14

Cita:

Empezado por mamcx (Mensaje 551143)
Este tipo de tareas se resuelve mejor con FTS:

https://learn.microsoft.com/en-us/sq...l-server-ver16

estuve leyendo esta opcion que me sugiere y si efectivamente creo que puedo lograr obtener los resultado deseado. ahora bien es posible crear una tabla temporal dentro del from? una tabla que soporte storprocedure, indices etc. digo eso porque si hago esto dentro de la base de dato pudiera chocar con otro usuario ya que el sistema sera usado simultaneamente por otros usuarios. esta tabla seria temporal ya que solamente se utilizaria para separar el string por palabras luego deberá destruirse.

giantonti1801 14-04-2023 03:51:44

Cita:

Empezado por mamcx (Mensaje 551143)
Este tipo de tareas se resuelve mejor con FTS:

https://learn.microsoft.com/en-us/sq...l-server-ver16

estube tratando de hacer algunas pruebas pero no se puede aplicar a SQLSERVER

mamcx 14-04-2023 04:45:28

Cita:

Empezado por giantonti1801 (Mensaje 551150)
estuve leyendo esta opcion que me sugiere y si efectivamente creo que puedo lograr obtener los resultado deseado. ahora bien es posible crear una tabla temporal dentro del from? una tabla que soporte storprocedure, indices etc. digo eso porque si hago esto dentro de la base de dato pudiera chocar con otro usuario ya que el sistema sera usado simultaneamente por otros usuarios. esta tabla seria temporal ya que solamente se utilizaria para separar el string por palabras luego deberá destruirse.

Estas comprendiendo mal la idea. No tienes que procesar nada con FTS, solo aplicarlo, el se encarga de todo el resto (FTS es un "indice" especializado. Asi como no manejas la lógica de un BTREE tampoco la de un FTS)


La franja horaria es GMT +2. Ahora son las 19:39:13.

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