Comunidad de diseño web y desarrollo en internet online

consulta SQL

Citar            
MensajeEscrito el 21 Ene 2009 01:34 pm
Hola gente, estaba buscando el foro más apropiado y parece ser este, aunque no sea extrictamente la temática por tratarse de ASP con consultas a bbdd Access. Como se trata de SQL quizá la cosa tampoco cambie mucho.

A ver si alguien me puede ayudar porque no soy un 'Soul Master' de la programación y llevo ya 2 noches sin ser capaz de avanzar.

Tengo una base de datos con un listado de conciertos, en la tabla 'conciertos'... en concreto me centro en 2 campos, 'grupos' [texto] y 'participantes' [memo]. En el primer campo van los grupos que actuan solos o como cabeza de cartel y también el nombre de festivales, y en el segundo campo, los demás grupos de un cartel o los participantes del festival (ej: "+ AC/DC + BlackSabbath + Metallica + Mago de Oz + Marea + Los Suaves).

Por otra parte tengo una tabla de grupos registrados en la web llamada 'grupos'. Lo que pretendo hacer, es generar una lista con el número de actuaciones de cada grupo registrado (concretamente de la tabla 'grupos' y de su campo 'grupo'), y hacer un rank de los más activos. Así, si el grupo 'XXZ' ha actuado en 10 conciertos sólos y en 3 festivales, el resultado debería ser 13.

*una cosa a tener en cuenta es que quisiera que en la consulta discriminase a los grupos que no estan registrados en la tabla 'grupos' porque en la tabla 'conciertos' pueden insertarse conciertos de grupos registrados o no, pero lo interesante para los usuarios es tener un listado sólo de los grupos registrados.

Hacer un 'count' de los grupos que aparecen en la tabla de conciertos no me ha resultado dificil...

Código :

("SELECT TOP 10 Grupo, count(Grupo)AS concerts FROM conciertos WHERE Fecha BETWEEN #01-01-2009# And #31-12-2009#  GROUP BY Grupo ORDER BY count(Grupo) DESC")


El problema que tengo es hacer un count de las veces que aparece un determinado grupo en el campo 'participantes' (que sería con un LIKE xxx) y sumarselo al grupo correspondiente. Más dificil aun es para mi, hacer que en el listado vaya como criterio de búsqueda los registros del campo 'grupo' de la tabla 'grupos'

Es un poco lioso, espero haberlo explicado bien. Yo mientras iré probando cosas y dejando aquí lo que pueda evolucionar el tema para que en el futuro alguno no se tire tantas horas perdidas.

Gracias.

Por cierto... de lo que va saliendo, podéis ver el resultado en el lateral derecho de [url=www.milsegundos.com/musica_noticias.asp]

Por pitger

Claber

201 de clabLevel



Genero:Masculino  

Cáceres

firefox
Citar            
MensajeEscrito el 21 Ene 2009 06:34 pm
Partiendo solamente de los campos y el query que posteaste esto debería servirte:

Código MySQL :

SELECT TOP 10 g.grupo, COUNT(c.grupo) AS concerts
FROM conciertos c
INNER JOIN grupos g
ON c.grupo LIKE '%'&g.grupo&'%' OR c.participantes LIKE '%'&g.grupo&'%'
GROUP BY g.grupo ORDER BY count(c.grupo) DESC;
Solo por si acaso, lo que hace esa consulta es contar las veces que un grupo (que esté registrado en tu tabla grupos), ha estado en un concierto ya sea como grupo o como participante (refiriendome a los campos de tu tabla conciertos)

Según mis averiguaciones, el ampersand ( & ), se usa en MS Access para concatenar strings... Te digo esto por si me equivoco busques la función para concatenar y la reemplaces donde estan los &, la idea es concatenar '%' g.grupo '%'... Ahorita estoy desde linux, no tengo como probarlo...

Espero te sirva, saludos...

Por KB-27

Claber

301 de clabLevel



 

My very secret HQ

firefox
Citar            
MensajeEscrito el 21 Ene 2009 08:25 pm
A ver, he usado esto segun me indicas... (he interpretado 'c' como 'conciertos' y 'g' como 'grupos') el caso es que no funciona y no le veo el dato.

("SELECT TOP 10 grupos.grupo, COUNT(conciertos.grupo) AS concerts FROM conciertos INNER JOIN grupos, conciertos ON conciertos.grupo LIKE '%'&grupos.grupo&'%' OR conciertos.participantes LIKE '%'&grupos.grupo&'%' GROUP BY grupos.grupo ORDER BY count(conciertos.grupo) DESC")

El error, este:

Microsoft OLE DB Provider for ODBC Drivers error '80040e14'
[Microsoft][ODBC Microsoft Access Driver] Syntax error in FROM clause.

Por pitger

Claber

201 de clabLevel



Genero:Masculino  

Cáceres

firefox
Citar            
MensajeEscrito el 21 Ene 2009 08:48 pm
Pruebalo de la siguiente manera, tenias algo demás en el que tu escribiste

("SELECT TOP 10 grupos.grupo, COUNT(conciertos.grupo) AS concerts FROM conciertos INNER JOIN grupos ON conciertos.grupo LIKE '%'&grupos.grupo&'%' OR conciertos.participantes LIKE '%'&grupos.grupo&'%' GROUP BY grupos.grupo ORDER BY count(conciertos.grupo) DESC")

La consulta que te pase funciona en MySQL y PostgreSQL, claro, con unos pequeños cambios... Pero no tengo como y para ser sincero no conozco lo suficiente para probar en MS Acces... Igual averiguaré un poco a ver si te puedo ayudar...

Por KB-27

Claber

301 de clabLevel



 

My very secret HQ

firefox
Citar            
MensajeEscrito el 21 Ene 2009 09:12 pm
Pues nada, no va aunque ahora ya tenemos un dato evidente, este es el error:

Microsoft OLE DB Provider for ODBC Drivers error '80040e14'

[Microsoft][ODBC Microsoft Access Driver] Cannot join on Memo, OLE, or Hyperlink Object (conciertos.grupo ALike '%' & grupos.grupo & '%' Or conciertos.participantes ALike '%' & grupos.grupo & '%').

No se puede usar join con campos Memo... me lo veía venir por eso indiqué al principio que el campo 'participantes' era un campo Memo. Yo hice algo que tampoco ha funcionado pero que era esto:

("SELECT TOP 10 Grupo, count(Grupo)AS concerts FROM conciertos WHERE Fecha BETWEEN #01-01-2008# And #31-12-2008# AND (SELECT participantes, count(participantes) FROM conciertos WHERE Fecha BETWEEN #01-01-2008# AND #31-12-2008#) GROUP BY Grupo ORDER BY count(Grupo) DESC")

No se si usar la consulta al campo 'participantes' fuera del INNER JOIN, o de alguna otra forma o la otra forma que acabo de indicar va acertada (como digo no funciona, pero no se ni donde está el fallo).

Desde ya KB-27 gracias por tu ayuda!

Por pitger

Claber

201 de clabLevel



Genero:Masculino  

Cáceres

firefox
Citar            
MensajeEscrito el 21 Ene 2009 09:53 pm
Intercambié el puesto con una compañera de trabajo para probar pero no di con nada, en todo caso tienes razón con lo del tipo Memo, lo que puedes hacer averiguar bien como son y que tanto se puede hacer con los JOINS en MS Access y lo del campo tipo Memo... Pero el corazon de la consulta está en:

Código MySQL :

INNER JOIN grupos g ON c.grupo LIKE '%'&g.grupo&'%' OR c.participantes LIKE '%'&g.grupo&'%' 
Si definitivamente no puedes meter un campo tipo Memo en la consulta simplemente quita desde el OR inclusive, y te contará las veces que un grupo que este en tu tabla grupos aparece en grupo de tu tabla conciertos...

No he trabajado con Access así que realmente no se que tanto habría que cambiar la consulta que te pasé, si consigo un tiempo en la noche me pongo a ver en que te puedo ayudar...

Por KB-27

Claber

301 de clabLevel



 

My very secret HQ

msie7
Citar            
MensajeEscrito el 21 Ene 2009 10:08 pm
Eres un hacha. Ya has hecho mucho y esta no es tu guerra, si no tienes tiempo tampoco te vayas a quitar el sueño tu también.

A ver si alguien que sepa de bbdd de Access coincide de entrar por aquí y aporta algo de luz que yo ya no se qué hacer.

Por pitger

Claber

201 de clabLevel



Genero:Masculino  

Cáceres

firefox
Citar            
MensajeEscrito el 21 Ene 2009 10:45 pm
Hace un rato que me he metido en este foro para conseguir respuesta a un problema y considero de justicia aportar en lo que pueda.
Efectivamente un campo Memo en Access no se puede emplear en una JOIN.
Sugiero cambiar la estructura de datos, si ello es posible. Un posible diseño (seguro que hay más) podria se este:

Tabla CONCIERTOS(ID , NOMBRE)
Donde ID es un autonumerico y es la Clave de la table, sería el código de concierto. NOMBRE seria un string(255) que contendria el nombre del concierto (p.ej. "Woodstock", "Sonar 2008"...)

Tabla GRUPOS(ID , NOMBRE)
Donde ID es un autonumerico y es la Clave de la table y seria un código de grupo. NOMBRE seria un string(255) que contendría el nombre del grupo musical (p.ej. "AC/DC", "Saint Martin of the Field", "Jefferson Star Ship"...)

Tabla CONCIERTO_GRUPOS(ID_CONCER, ID_GRUPO)
Donde ID_CONCER es un Long Integer y ID_GRUPO también.
En esta última tabla guardarias el código de concierto y un código de grupo. Es decir en esta tabla guardarias los conciertos donde a tocado un grupo o también que grupos tocaron en un concierto. La propia tabla te solucinaria el recuento que planteabas al principio.

Por bosquimano

5 de clabLevel



 

firefox
Citar            
MensajeEscrito el 22 Ene 2009 12:36 pm
Pues si, bosquimano tiene razón, la solución más óptima es realizar una relación como la que explica, ya que hablando de normalización y bla bla bla de las tablas de la base de dato así es como deberia quedar... Lo único es que a veces no se puede replantear el diseño de una BD que está siendo utilizada así como así por X o Y razón, y no sé si pitger lo pueda hacer, por eso intentaba encontrarle una solución con la estructura que tiene actualmente...

Por KB-27

Claber

301 de clabLevel



 

My very secret HQ

firefox
Citar            
MensajeEscrito el 22 Ene 2009 05:01 pm
Bueno... Soy anciano en esto ... Pero por experiencia puedo decir que si hoy las tablas del Sr Pitger tiene más o menos 400 registros (o menos) de promedio hoy, el cambio sale a cuenta (¡y mucho!), si tienes muchos más registros, la decisión es más dificil de tomar. La busqueda que plantea es sencilla y sencilla deberia ser la consulta SQL. Si asi como tiene la estructura de datos hoy, se le hace tan complicada la consulta, cuando quiera hacer una busqueda complicada (que llegará ese día), la consulta SQL será imposible... Ya he pasado por eso ;-) ...

Por bosquimano

5 de clabLevel



 

firefox
Citar            
MensajeEscrito el 22 Ene 2009 06:15 pm
Si bosquimano, se que tienes razón con respecto a lo de la decisión de cambiar el diseño de la BD por el número de registros, y aún más en el problema que sería ejecutar una consulta mas compleja...

Todo es cuestión de que Pitger analice su data, diseño y necesidades, para ver si puede (o quiere) cambiar el diesño de la BD, incluyendo tipos de datos como Memo, no se para que sirve ni como se maneja, pero si genera conflictos para una consulta X deberia pensar si verdaderamente es el tipo de dato que mas le favorece...

Actualmente se lo que es trabajar con una BD que tiene un diseño... no malo, pero si ineficiente... en fin, esa es otra historia...

Por KB-27

Claber

301 de clabLevel



 

My very secret HQ

firefox
Citar            
MensajeEscrito el 23 Ene 2009 12:32 am
Si, también he pensado en cambiar la estructura la base de datos, es un coñazo porque habría que cambiar las consultas de muchas páginas asp pero ciertamente, si la cosa puede irse complicando cada vez más, mejor empezar a corregir ahora.

Desgraciadamente el problema es mas dificil de lo que parece... como ya dije, en la tabla 'conciertos' se pueden añadir conciertos de grupos registrados en la tabla 'grupos' o no registrados.

La clave parece estar en que utilizo la tabla 'conciertos' para añadir festivales también, poniendo el nombre del festival en el campo 'grupo' y los participantes en 'participantes'... evidentemente un festival tiene muchos más grupos que un concierto en un local, donde como mucho actúan 4 o 5 grupos. Al usar ese campo 'participantes' para poner los participantes de un festival, obligatoriamente se sobrepasarán los 255 carácteres y es ahí donde se lia todo.

Tuve esperanzas de que de alguna forma funcionase porque curiosamente cuando uso una variable (el nombre de un grupo) y que la paso por GET, la consulta sobre el campo memo si funciona... ved el ejemplo en la columna de la derecha: enlace En ese caso la consulta usada es la siguiente:

codigo escribió:

("SELECT TOP 10 Grupo, count(Grupo)AS concerts FROM conciertos WHERE Grupo LIKE '%" & nombre & "%' OR participantes LIKE '%" & nombre & "%' GROUP BY Grupo ORDER BY count(Grupo) DESC")


Evidentemente ahí sólo faltaba unir todos esos eventos en 1 sólo que englobase o sumase todas las apariciones del grupo en cuestion, en vez de desglosarlas como lo hace ahí.

Da la impresion pues que una busqueda sobre campos 'memo' si funciona si el criterio de busqueda es un valor fijo. He estado usando subconsultas pero tampoco me funcionó. Creo que la solución pasa por crear una tabla mas que sea Festivales con un campo 'nombre' para el nombre del festival y varios campos para los grupos y que podrían ser estos:

##TABLA:FESTIVALES##
-Id [autonumerico] *Campo clave.
-GruposNoReg [memo] *grupos que tocan el 1er. dia y que no están registrados en la web
-GruposReg [text] *grupos que tocan el 1er. dia y que si estan registrados en la web (se pondría su id numérica)
-Fecha [date] *fecha del festival. Si son varios dias se ponen el el 2º dia los grupos que actuan ese dia y asi sucesivamente.

Siendo esta tercera tabla y teniendo en cuenta que en mi tabla 'grupos' existe ya un campo clave 'id' autonumérico ¿como sería la consulta para hacer lo que preguntaba al principio?

probando una consulta escribió:


("SELECT TOP 10 grupos.id, grupos.grupo, COUNT(conciertos.grupo) AS concerts FROM conciertos INNER JOIN grupos ON conciertos.grupo LIKE '%'&grupos.grupo&'%' INNER JOIN festivales ON festivales.GruposReg LIKE '%'&grupos.id&'%' GROUP BY grupos.grupo ORDER BY count(conciertos.grupo)+count(festivales.GruposReg) DESC")


Intuyo que está mal porque sólo se hacer consultas simples y no se si los INNER JOINS se enlazan de esta forma, pero la idea es sacar datos de 3 tablas (grupos, conciertos, festivales) y unir todos los resultados en un único registro donde el campo común es el Grupo y el otro campo un contador de las veces que aparece en la tabla conciertos + las veces que aparece en festivales.

A todo esto, le faltaba especificar que necesito que sea en un intervalo de fecha del 1-1-08 al 31-12-08 (pa mandarme a tomar por culo, vamos!)

Por pitger

Claber

201 de clabLevel



Genero:Masculino  

Cáceres

firefox
Citar            
MensajeEscrito el 23 Ene 2009 12:43 am
Por cierto KB-27, la consulta que me pasaste...

KB-27 me pasó la sql.... escribió:

("SELECT TOP 10 grupos.grupo, COUNT(conciertos.grupo) AS concerts FROM conciertos INNER JOIN grupos ON conciertos.grupo LIKE '%'&grupos.grupo&'%' OR conciertos.participantes LIKE '%'&grupos.grupo&'%' GROUP BY grupos.grupo ORDER BY count(conciertos.grupo) DESC")


....es más precisa que la que yo tenía porque sólo incluye los grupos que estan registrados (Biennnn!! :) )pero como vimos, no funcionaba sobre el campo memo, total que le quité lo del campo memo dejandola así....

consulta de KB-27 quitando campo memo... escribió:

("SELECT TOP 10 grupos.grupo, COUNT(conciertos.grupo) AS concerts FROM conciertos INNER JOIN grupos ON conciertos.grupo LIKE '%'&grupos.grupo&'%' GROUP BY grupos.grupo ORDER BY count(conciertos.grupo) DESC")


... ahora, me di cuenta de un pequeño detalle ( :? quizá no tan pequeño) y es que no se le puso el intervalo de fechas (que sea sólo del año 2008 osea, del 1 de enero al 31 de diciembre), yo lo estuve intentando pero me da fallo y no se ni donde ni porqué. Hice así...

consulta de KB-27 añadiendo fechas... escribió:

("SELECT TOP 10 grupos.grupo, COUNT(conciertos.grupo) AS concerts FROM conciertos INNER JOIN grupos ON conciertos.grupo LIKE '%'&grupos.grupo&'%' AND Fecha BETWEEN #01-01-2009# And #31-12-2009# GROUP BY grupos.grupo ORDER BY count(conciertos.grupo) DESC")

Por pitger

Claber

201 de clabLevel



Genero:Masculino  

Cáceres

firefox
Citar            
MensajeEscrito el 23 Ene 2009 12:57 pm
¿Probaste poniendo conciertos.Fecha?

Por KB-27

Claber

301 de clabLevel



 

My very secret HQ

firefox
Citar            
MensajeEscrito el 23 Ene 2009 03:47 pm

KB-27 escribió:

¿Probaste poniendo conciertos.Fecha?


Vaya, pues ahora me dejas con la duda, no se si lo hice así... ahora mismo sólo estoy viendo los mails y tengo que salir pitando a ver a unos clientes pero esta noche (horario de España) te comento.

Por pitger

Claber

201 de clabLevel



Genero:Masculino  

Cáceres

firefox
Citar            
MensajeEscrito el 24 Ene 2009 02:09 pm
Pues no, da error y además un tanto curioso (si es que debo tener gafe con las consultas SQL)

Uso este sql...

sql escribió:

("SELECT TOP 10 grupos.grupo, COUNT(conciertos.grupo) AS concerts FROM conciertos INNER JOIN grupos ON conciertos.grupo LIKE '%'&grupos.grupo&'%' AND conciertos.Fecha BETWEEN #01-01-2009# And #31-12-2009# GROUP BY grupos.grupo ORDER BY count(conciertos.grupo) DESC")


y el server me responde:

sql escribió:

Microsoft OLE DB Provider for ODBC Drivers error '80040e14'
[Microsoft][ODBC Microsoft Access Driver] Between operator without And in query expression ''.


¿como que sin AND? Yo ya no entiendo nada..

Por pitger

Claber

201 de clabLevel



Genero:Masculino  

Cáceres

firefox

 

Cristalab BabyBlue v4 + V4 © 2011 Cristalab
Powered by ClabEngines v4, HTML5, love and ponies.