Optimizar filtrado en varias tablas

03/05/2007 - 15:59 por Juan Diego Bueno | Informe spam
Hola gente:

Estoy desarrollando actualmente un proyecto en C# 2.0 + SQL Server
2005. El sistema de filtrado que he implementado se basa en una vista
obtenida a partir de una tabla principal (candidatos) y varias
relacionadas con Left outer join.

El tema es que la vista devuelve varias veces el mismo candidato (como
cabría de esperar) en función de las ocurrencias en cada una de las
tablas de relación y con combinación cartesiana, de tal forma que si
por un casual tiene n registros en una, m en otro y así
sucesivamente, puede aparecer n x m x ... veces el mismo candidato, lo
cual cuando la base de datos se cubra con una cantidad considerable de
candidatos y sus datos relacionados, puede dar una vista que devuelva
muchísimos registros.

¿Alguna forma de poder realizar esta consulta de manera que devuelva
los menos registros posibles?. O en su defecto alguna alternativa
eficaz a este sistema.

Gracias de antemano

Saludos

Preguntas similare

Leer las respuestas

#1 Maxi
03/05/2007 - 16:05 | Informe spam
Hola, la verdad que no sabemos, y no lo sabemos porque no sabemos que has
hecho, para poderte ayudar debes mostrarnos que hicistes amigo, es
importante que nos envies:

1) DDL de tablas
2) query
3) Resultados esperados



Salu2

Microsoft MVP SQL Server
Culminis Speaker

"Juan Diego Bueno" escribió en el mensaje
news:
Hola gente:

Estoy desarrollando actualmente un proyecto en C# 2.0 + SQL Server
2005. El sistema de filtrado que he implementado se basa en una vista
obtenida a partir de una tabla principal (candidatos) y varias
relacionadas con Left outer join.

El tema es que la vista devuelve varias veces el mismo candidato (como
cabría de esperar) en función de las ocurrencias en cada una de las
tablas de relación y con combinación cartesiana, de tal forma que si
por un casual tiene n registros en una, m en otro y así
sucesivamente, puede aparecer n x m x ... veces el mismo candidato, lo
cual cuando la base de datos se cubra con una cantidad considerable de
candidatos y sus datos relacionados, puede dar una vista que devuelva
muchísimos registros.

¿Alguna forma de poder realizar esta consulta de manera que devuelva
los menos registros posibles?. O en su defecto alguna alternativa
eficaz a este sistema.

Gracias de antemano

Saludos
Respuesta Responder a este mensaje
#2 Jose Mariano Alvarez
03/05/2007 - 16:24 | Informe spam
En el post ,
DIJO .
de relación y con combinación cartesiana,






Por que realizas un producto cartesiano de las tablas?



Saludos
Ing. Jose Mariano Alvarez


(Cambia los ceros por O y saca lo que sobra)


IMPORTANTE

Por favor traten de indicar la versión de SQL y Service Pack.
La inclusión de (CREATE, INSERTS, etc.) para poder reproducir el
problema también ayuda.
Respuesta Responder a este mensaje
#3 Juan Diego Bueno
03/05/2007 - 16:31 | Informe spam
Bueno, pensé que con una explicación genérica bastaba, pero aquí
tienes el select de las tablas (obviamente de las tablas base no voy a
mandar el DDL puesto que son unas cuantas, pero es fácilmente
deducible, todas son relaciones M:M)

SELECT
C.NIF, C.APELLIDOS + ', ' + C.NOMBRE AS
NOMBRE_COMPLETO, C.FECHA_NAC, C.TLF_MOVIL, C.TLF_FIJO, C.EMAIL,
C.LOCALIDAD,
P.DEN_PROVINCIA, CASE INTERNO WHEN 1 THEN 'SI'
WHEN 0 THEN 'NO' END AS C_INTERNO, C.INTERNO, C.COD_PROVINCIA,
C.ESTADO_CIVIL,
C.NACIONALIDAD, ISNULL(EC.COD_TITULACION, '') AS
COD_TITULACION, ISNULL(T.COD_NIVEL_TIT, '') AS NIVEL_TITULACION,
EC.FECHA_INI AS FECHA_INI_EST, EC.FECHA_FIN AS
FECHA_FIN_EST, ISNULL(EXC.EMPRESA, '') AS EMPRESA, EXC.FECHA_INI AS
FECHA_INI_EXP,
EXC.FECHA_FIN AS FECHA_FIN_EXP,
ISNULL(EXC.PUESTO, '') AS PUESTO, ISNULL(EXC.DESCRIPCION, '') AS
DESCRIPCION,
ISNULL(ESEST.COD_ESP, '') AS COD_ESP_EST,
ISNULL(ESEST.COD_ANYOS_EXP, 0) AS COD_ANYOS_ESPEST,
ISNULL(ESEXP.COD_ESP, '')
AS COD_ESP_EXP, ISNULL(ESEXP.COD_ANYOS_EXP, 0)
AS COD_ANYOS_ESPEXP, ISNULL(I.COD_IDIOMA, '') AS COD_IDIOMA,
ISNULL(I.LEIDO, '0')
AS LEIDO, ISNULL(I.HABLADO, '0') AS HABLADO,
ISNULL(I.ESCRITO, '0') AS ESCRITO, ISNULL(I.TITULO, '') AS TITULO
FROM dbo.SQL_CANDIDATOS AS C LEFT OUTER JOIN
dbo.SQL_PROVINCIAS AS P ON C.COD_PROVINCIA P.COD_PROVINCIA LEFT OUTER JOIN
dbo.SQL_ESTUDIOS_CAND AS EC ON C.NIF = EC.NIF
LEFT OUTER JOIN
dbo.SQL_TITULACIONES AS T ON EC.COD_TITULACION T.COD_TITULACION LEFT OUTER JOIN
dbo.SQL_EXPERIENCIA_CAND AS EXC ON C.NIF EXC.NIF LEFT OUTER JOIN
dbo.SQL_ESP_EST_CAND AS ESEST ON C.NIF ESEST.NIF LEFT OUTER JOIN
dbo.SQL_ESP_EXP_CAND AS ESEXP ON C.NIF ESEXP.NIF LEFT OUTER JOIN
dbo.SQL_IDIOMAS_CAND AS I ON C.NIF = I.NIF

Todas las tablas con las que hago el join son tablas de relación de
los candidatos con otras tablas.

El resultado es el esperado... a medias, puesto que si por ejemplo un
candidato tiene varias ocurrencias en SQL_ESTUDIOS_CANS y varias en
SQL_EXPERIENCIA muestra la combinación cartesiana de ambos. Viendo la
cantidad de tablas con las que se relacionan y previendo que cada uno
de los candidatos tenga varios registros relacionados en cada tabla,
la vista podría devolver una cantidad considerable de registros. Busco
otra forma de construir la consulta o alguna alternativa para realizar
el filtrado.

Saludos

On 3 mayo, 16:05, "Maxi" wrote:
Hola, la verdad que no sabemos, y no lo sabemos porque no sabemos que has
hecho, para poderte ayudar debes mostrarnos que hicistes amigo, es
importante que nos envies:

1) DDL de tablas
2) query
3) Resultados esperados


Salu2

Microsoft MVP SQL Server
Culminis Speaker

"Juan Diego Bueno" escribió en el mensajenews:
Hola gente:

Estoy desarrollando actualmente un proyecto en C# 2.0 + SQL Server
2005. El sistema de filtrado que he implementado se basa en una vista
obtenida a partir de una tabla principal (candidatos) y varias
relacionadas con Left outer join.

El tema es que la vista devuelve varias veces el mismo candidato (como
cabría de esperar) en función de las ocurrencias en cada una de las
tablas de relación y con combinación cartesiana, de tal forma que si
por un casual tiene n registros en una, m en otro y así
sucesivamente, puede aparecer n x m x ... veces el mismo candidato, lo
cual cuando la base de datos se cubra con una cantidad considerable de
candidatos y sus datos relacionados, puede dar una vista que devuelva
muchísimos registros.

¿Alguna forma de poder realizar esta consulta de manera que devuelva
los menos registros posibles?. O en su defecto alguna alternativa
eficaz a este sistema.

Gracias de antemano

Saludos
Respuesta Responder a este mensaje
#4 Jesús López
03/05/2007 - 19:53 | Informe spam
Mi opinion es que un único conjunto de registros es inadecuado para
describir toda la información requerida. Mi recomendación sería que usaras
varias vistas para obtener toda la información en vez de una sola.

Saludos:

Jesús López
www.solidqualitylearning.com



"Juan Diego Bueno" escribió en el mensaje
news:
Bueno, pensé que con una explicación genérica bastaba, pero aquí
tienes el select de las tablas (obviamente de las tablas base no voy a
mandar el DDL puesto que son unas cuantas, pero es fácilmente
deducible, todas son relaciones M:M)

SELECT
C.NIF, C.APELLIDOS + ', ' + C.NOMBRE AS
NOMBRE_COMPLETO, C.FECHA_NAC, C.TLF_MOVIL, C.TLF_FIJO, C.EMAIL,
C.LOCALIDAD,
P.DEN_PROVINCIA, CASE INTERNO WHEN 1 THEN 'SI'
WHEN 0 THEN 'NO' END AS C_INTERNO, C.INTERNO, C.COD_PROVINCIA,
C.ESTADO_CIVIL,
C.NACIONALIDAD, ISNULL(EC.COD_TITULACION, '') AS
COD_TITULACION, ISNULL(T.COD_NIVEL_TIT, '') AS NIVEL_TITULACION,
EC.FECHA_INI AS FECHA_INI_EST, EC.FECHA_FIN AS
FECHA_FIN_EST, ISNULL(EXC.EMPRESA, '') AS EMPRESA, EXC.FECHA_INI AS
FECHA_INI_EXP,
EXC.FECHA_FIN AS FECHA_FIN_EXP,
ISNULL(EXC.PUESTO, '') AS PUESTO, ISNULL(EXC.DESCRIPCION, '') AS
DESCRIPCION,
ISNULL(ESEST.COD_ESP, '') AS COD_ESP_EST,
ISNULL(ESEST.COD_ANYOS_EXP, 0) AS COD_ANYOS_ESPEST,
ISNULL(ESEXP.COD_ESP, '')
AS COD_ESP_EXP, ISNULL(ESEXP.COD_ANYOS_EXP, 0)
AS COD_ANYOS_ESPEXP, ISNULL(I.COD_IDIOMA, '') AS COD_IDIOMA,
ISNULL(I.LEIDO, '0')
AS LEIDO, ISNULL(I.HABLADO, '0') AS HABLADO,
ISNULL(I.ESCRITO, '0') AS ESCRITO, ISNULL(I.TITULO, '') AS TITULO
FROM dbo.SQL_CANDIDATOS AS C LEFT OUTER JOIN
dbo.SQL_PROVINCIAS AS P ON C.COD_PROVINCIA P.COD_PROVINCIA LEFT OUTER JOIN
dbo.SQL_ESTUDIOS_CAND AS EC ON C.NIF = EC.NIF
LEFT OUTER JOIN
dbo.SQL_TITULACIONES AS T ON EC.COD_TITULACION T.COD_TITULACION LEFT OUTER JOIN
dbo.SQL_EXPERIENCIA_CAND AS EXC ON C.NIF EXC.NIF LEFT OUTER JOIN
dbo.SQL_ESP_EST_CAND AS ESEST ON C.NIF ESEST.NIF LEFT OUTER JOIN
dbo.SQL_ESP_EXP_CAND AS ESEXP ON C.NIF ESEXP.NIF LEFT OUTER JOIN
dbo.SQL_IDIOMAS_CAND AS I ON C.NIF = I.NIF

Todas las tablas con las que hago el join son tablas de relación de
los candidatos con otras tablas.

El resultado es el esperado... a medias, puesto que si por ejemplo un
candidato tiene varias ocurrencias en SQL_ESTUDIOS_CANS y varias en
SQL_EXPERIENCIA muestra la combinación cartesiana de ambos. Viendo la
cantidad de tablas con las que se relacionan y previendo que cada uno
de los candidatos tenga varios registros relacionados en cada tabla,
la vista podría devolver una cantidad considerable de registros. Busco
otra forma de construir la consulta o alguna alternativa para realizar
el filtrado.

Saludos

On 3 mayo, 16:05, "Maxi" wrote:
Hola, la verdad que no sabemos, y no lo sabemos porque no sabemos que has
hecho, para poderte ayudar debes mostrarnos que hicistes amigo, es
importante que nos envies:

1) DDL de tablas
2) query
3) Resultados esperados


Salu2

Microsoft MVP SQL Server
Culminis Speaker

"Juan Diego Bueno" escribió en el
mensajenews:
Hola gente:

Estoy desarrollando actualmente un proyecto en C# 2.0 + SQL Server
2005. El sistema de filtrado que he implementado se basa en una vista
obtenida a partir de una tabla principal (candidatos) y varias
relacionadas con Left outer join.

El tema es que la vista devuelve varias veces el mismo candidato (como
cabría de esperar) en función de las ocurrencias en cada una de las
tablas de relación y con combinación cartesiana, de tal forma que si
por un casual tiene n registros en una, m en otro y así
sucesivamente, puede aparecer n x m x ... veces el mismo candidato, lo
cual cuando la base de datos se cubra con una cantidad considerable de
candidatos y sus datos relacionados, puede dar una vista que devuelva
muchísimos registros.

¿Alguna forma de poder realizar esta consulta de manera que devuelva
los menos registros posibles?. O en su defecto alguna alternativa
eficaz a este sistema.

Gracias de antemano

Saludos
Respuesta Responder a este mensaje
#5 Juan Diego Bueno
03/05/2007 - 20:21 | Informe spam
Bien, Jesús, yo estoy de acuerdo pero entonces ¿cómo puedo hacer el filtrado
de forma fácil?. Ten en cuenta que parte de esa vista se va a mostrar luego
en un grid. Lo más parecido que se me ocurre es obtener mediante filtrado
los NIFS en cada una de las tablas y hacer un select where nif in
(listadenifs) pero lo veo más complicado de implementar y tampoco tengo muy
claro cómo. Otra idea que pensé consiste en usar campos con valores
múltiples en la vista, es decir, para cada nif un campo titulaciones que
contenga separadas por comas todas las titulaciones de ese nif (aunque este
tipo de consulta tampoco he pensado como se puede hacer).

Gracias de antemano

Saludos

"Jesús López" escribió en el mensaje
news:
Mi opinion es que un único conjunto de registros es inadecuado para
describir toda la información requerida. Mi recomendación sería que usaras
varias vistas para obtener toda la información en vez de una sola.

Saludos:

Jesús López
www.solidqualitylearning.com



"Juan Diego Bueno" escribió en el mensaje
news:
Bueno, pensé que con una explicación genérica bastaba, pero aquí
tienes el select de las tablas (obviamente de las tablas base no voy a
mandar el DDL puesto que son unas cuantas, pero es fácilmente
deducible, todas son relaciones M:M)

SELECT
C.NIF, C.APELLIDOS + ', ' + C.NOMBRE AS
NOMBRE_COMPLETO, C.FECHA_NAC, C.TLF_MOVIL, C.TLF_FIJO, C.EMAIL,
C.LOCALIDAD,
P.DEN_PROVINCIA, CASE INTERNO WHEN 1 THEN 'SI'
WHEN 0 THEN 'NO' END AS C_INTERNO, C.INTERNO, C.COD_PROVINCIA,
C.ESTADO_CIVIL,
C.NACIONALIDAD, ISNULL(EC.COD_TITULACION, '') AS
COD_TITULACION, ISNULL(T.COD_NIVEL_TIT, '') AS NIVEL_TITULACION,
EC.FECHA_INI AS FECHA_INI_EST, EC.FECHA_FIN AS
FECHA_FIN_EST, ISNULL(EXC.EMPRESA, '') AS EMPRESA, EXC.FECHA_INI AS
FECHA_INI_EXP,
EXC.FECHA_FIN AS FECHA_FIN_EXP,
ISNULL(EXC.PUESTO, '') AS PUESTO, ISNULL(EXC.DESCRIPCION, '') AS
DESCRIPCION,
ISNULL(ESEST.COD_ESP, '') AS COD_ESP_EST,
ISNULL(ESEST.COD_ANYOS_EXP, 0) AS COD_ANYOS_ESPEST,
ISNULL(ESEXP.COD_ESP, '')
AS COD_ESP_EXP, ISNULL(ESEXP.COD_ANYOS_EXP, 0)
AS COD_ANYOS_ESPEXP, ISNULL(I.COD_IDIOMA, '') AS COD_IDIOMA,
ISNULL(I.LEIDO, '0')
AS LEIDO, ISNULL(I.HABLADO, '0') AS HABLADO,
ISNULL(I.ESCRITO, '0') AS ESCRITO, ISNULL(I.TITULO, '') AS TITULO
FROM dbo.SQL_CANDIDATOS AS C LEFT OUTER JOIN
dbo.SQL_PROVINCIAS AS P ON C.COD_PROVINCIA > P.COD_PROVINCIA LEFT OUTER JOIN
dbo.SQL_ESTUDIOS_CAND AS EC ON C.NIF = EC.NIF
LEFT OUTER JOIN
dbo.SQL_TITULACIONES AS T ON EC.COD_TITULACION > T.COD_TITULACION LEFT OUTER JOIN
dbo.SQL_EXPERIENCIA_CAND AS EXC ON C.NIF > EXC.NIF LEFT OUTER JOIN
dbo.SQL_ESP_EST_CAND AS ESEST ON C.NIF > ESEST.NIF LEFT OUTER JOIN
dbo.SQL_ESP_EXP_CAND AS ESEXP ON C.NIF > ESEXP.NIF LEFT OUTER JOIN
dbo.SQL_IDIOMAS_CAND AS I ON C.NIF = I.NIF

Todas las tablas con las que hago el join son tablas de relación de
los candidatos con otras tablas.

El resultado es el esperado... a medias, puesto que si por ejemplo un
candidato tiene varias ocurrencias en SQL_ESTUDIOS_CANS y varias en
SQL_EXPERIENCIA muestra la combinación cartesiana de ambos. Viendo la
cantidad de tablas con las que se relacionan y previendo que cada uno
de los candidatos tenga varios registros relacionados en cada tabla,
la vista podría devolver una cantidad considerable de registros. Busco
otra forma de construir la consulta o alguna alternativa para realizar
el filtrado.

Saludos

On 3 mayo, 16:05, "Maxi" wrote:
Hola, la verdad que no sabemos, y no lo sabemos porque no sabemos que has
hecho, para poderte ayudar debes mostrarnos que hicistes amigo, es
importante que nos envies:

1) DDL de tablas
2) query
3) Resultados esperados


Salu2

Microsoft MVP SQL Server
Culminis Speaker

"Juan Diego Bueno" escribió en el
mensajenews:
Hola gente:

Estoy desarrollando actualmente un proyecto en C# 2.0 + SQL Server
2005. El sistema de filtrado que he implementado se basa en una vista
obtenida a partir de una tabla principal (candidatos) y varias
relacionadas con Left outer join.

El tema es que la vista devuelve varias veces el mismo candidato (como
cabría de esperar) en función de las ocurrencias en cada una de las
tablas de relación y con combinación cartesiana, de tal forma que si
por un casual tiene n registros en una, m en otro y así
sucesivamente, puede aparecer n x m x ... veces el mismo candidato, lo
cual cuando la base de datos se cubra con una cantidad considerable de
candidatos y sus datos relacionados, puede dar una vista que devuelva
muchísimos registros.

¿Alguna forma de poder realizar esta consulta de manera que devuelva
los menos registros posibles?. O en su defecto alguna alternativa
eficaz a este sistema.

Gracias de antemano

Saludos





Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida