Foros del Web » Programando para Internet » PHP »

Separación de registros iguales: PHP Mysql

Estas en el tema de Separación de registros iguales: PHP Mysql en el foro de PHP en Foros del Web. Hola a todos, Se que cuando se ve un post tan largo como este no dan ni ganas de leerlo, pero para lo siguiente me ...
  #1 (permalink)  
Antiguo 19/12/2005, 19:35
Avatar de hieloverde  
Fecha de Ingreso: julio-2005
Ubicación: México, D.F
Mensajes: 467
Antigüedad: 12 años, 5 meses
Puntos: 5
Pregunta Separación de registros iguales: PHP Mysql

Hola a todos,

Se que cuando se ve un post tan largo como este no dan ni ganas de leerlo, pero para lo siguiente me gustarían mucho las opiniones de los más phperos posibles o de cualquiera que pueda dar una idea, solo necesito un empujón con la lógica. Del código yo me encargo. Es que ya llevo varios días encerrado en el problema, no pido todo hecho, solo un pequeño aventón.

Estoy haciendo un pequeño selector de registros (canciones para ser mas exacto) en PHP y Mysql. De una lista de categorías se tienen que seleccionar las canciones correspondientes, pero la selección tiene que empezar con aquellas que contengan menos canciones.

Las categorías están contenidas en un array secuencial, asi:

Código PHP:
/* Estas son las categorias */
$categoria[0]='POP'/* Tiene 10 canciones */
$categoria[1]='BALADA'/* Tiene 25 canciones */
$categoria[2]='RANCHERO';/* Tiene 5 canciones */
$categoria[3]='BANDA'/* Tiene 6 canciones */ 
Como pueden apreciar las categorías no están ordenadas por el numero de melodías sino por el orden que el usuario le da en un principio, para ordenarlas hago un conteo de las canciones que tiene cada una y los almaceno en otro array llamado $conteo respetando los índices y luego ordeno el array por valores usando la función asort() para que una vez echa la selección de las canciones pueda volver a ordenarlas y mostrarlas en pantalla como debe ser:

El orden por número de canciones quedaria así:

Código PHP:
/* Estas son las categorias ordenadas por el numero de canciones */
$conteo[2]=5/* RANCHERO */
$conteo[3]=6/* BANDA */
$conteo[0]=10/* POP */
$conteo[1]=25/* BALADA */ 
Entonces basándome en los índices reordenados por numero hago la selección de las canciones, 2,3,0,1. Esto lo hago sin problemas, el problema real comienza al implementar una separación de interprete, esto es para que el mismo interprete de una cancion no pueda ser seleccionado sino hasta que pasen un numero determinado de canciones de otros interpretes distintos, por ejemplo 10 o sea el interprete no se puede seleccionar hasta que pasen 10 canciones como mínimo.

Y como la selección la hago dependiendo el numero de canciones de cada categoría y no en el orden en que se van a mostrar en pantalla (como quiere el usuario) pues no se como controlar la separación de los interpretes. Probé almacenado los interpretes en una tabla aparte conforme se van seleccionando y usando en la consulta para seleccionar la canción la cláusula “NOT IN” pero no me funciono por que el orden en que se eligen las canciones no es como se van a mostrar al final, entonces nunca va a quedar la separación correctamente. Se entiende?

Espero que alguien me pueda dar alguna idea de cómo se puede implementar la lógica para separar los interpretes, si algo no quedo entendible háganme saber que parte no es clara y lo vuelvo a explicar.

Saludos y de antemano 1000 gracias.
__________________
<? echo("1 <script> dice + que 1000 palabras"); ?> EspacioMéxico
  #2 (permalink)  
Antiguo 20/12/2005, 05:45
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 15 años, 11 meses
Puntos: 126
Dices o das a entender en algún punto:
Cita:
Probé almacenado los interpretes en una tabla aparte conforme se van seleccionando y usando en la consulta para seleccionar la canción la cláusula “NOT IN” pero no me funciono por que el orden en que se eligen las canciones no es como se van a mostrar al final, entonces nunca va a quedar la separación correctamente. Se entiende?
Que .. esos datos los almacenas en una Base de datos y de ahí los obtienes? .. Si es así .. trabaja todo lo que requieres hacer con SQL en la medida de lo posible. Una sentencia SQL más compleja que tal vez ahora no dominas aliviaría mucho todos los problemas de lógica para implementar eso mismo en "PHP" cosa que SQL ya es un "lenguaje" de por sí (Lenguaje estructurado de consultas).

Confirma si realmente usas Base de datos, indica cual (mysql?) .. indica la estructura de esta y algunos datos de prueba. Con eso .. sería recomendable que consultes en el foro de "Base de datos" por la consulta(S) SQL más adecuadas para obtener tus datos de esa tabla.

Cita:
Se que cuando se ve un post tan largo como este no dan ni ganas de leerlo,
Realmente el que tenga ganas de responder se lo leerá completo y agradecerá la exposición del tema completo. Otra cosa será que despues de haber leido tu exposión no quede claro .. en ese caso se te solicitará información extra, realizar tal prueba .. leer tal documento/FAQ .. etc.

Un saludo,
  #3 (permalink)  
Antiguo 20/12/2005, 12:06
Avatar de hieloverde  
Fecha de Ingreso: julio-2005
Ubicación: México, D.F
Mensajes: 467
Antigüedad: 12 años, 5 meses
Puntos: 5
Si, me falto explicar la forma en que se da el almacenamiento de los datos, a continuación explicare la mecánica:

Primero, confirmo que uso base de datos Mysql.

Como dije antes trabajo en la elaboración de un selector de canciones, por supuesto los datos de cada canción son almacenados en una tabla llamada ‘melodias’, dicha tabla tiene los siguientes campos:

id int(11) not null auto_increment primary key,
Titulo varchar(100) not null,
Autor varchar(100) not null,
Compositor varchar(100) not null,
Interprete varchar(100) not null,
Genero varchar(30) not null,
Duracion varchar(10) not null,
INTRO varchar(10) not null,
Categoria varchar(50) not null,
Estado varchar(10) DEFAULT 'Visible' not null,
Fecha_alta varchar(10) not null,
Fecha_mod varchar(10) not null,
Historial int(11) DEFAULT '0' not null,
Tocada int(11) DEFAULT '0' not null,
Ruta varchar(255) not null,

Ahora estos registros (canciones) se dividen principalmente por el campo ‘Categoria’ (POP, BALADA, RANCHERO y BANDA), entonces el usuario solicita distintas categorías y a partir de esas categorías solicitadas se deben seleccionar las canciones para obtener datos como: Titulo, Intérprete, Duración, etc.

Pero también el usuario debe poder especificar el número mínimo de canciones para repetir un mismo intérprete, esto es para que no salgan pegadas dos canciones del mismo interprete (el interprete de cada canción se almacena en el campo ‘Interprete’).

Tengo una tabla destinada para almacenar los intérpretes que se van seleccionando, llamada ‘bloqueo’ y tiene el siguiente campo:

Interprete varchar(100) not null primary key,

Si las canciones se fueran seleccionando en el orden que el usuario las solicito, no tendría problema en implementar la separación de intérprete, por que solo tendría que mantener un numero determinado de interpretes conforme se van seleccionando en la tabla ‘bloqueo’ y así aplicar la subconsulta SQL correspondiente para evitar que se junten interpretes iguales.

Para esto venia usando la siguienete consulta
Código PHP:
$s="melodias";
mysql_query("SELECT ".$s.".* FROM ".$s." LEFT JOIN bloqueo ON ".$s.".Interprete = bloqueo.Interprete WHERE bloqueo.Interprete IS NULL and ".$s.".Categoria='".$categoria[$x]."'"); 
Pero no es tan simple o al menos no lo es para mi, ya que las canciones tienen que ser seleccionadas dependiendo el numero de canciones que tenga la categoría correspondiente (de menor a mayor), la lógica de esto es seleccionar primero las categorías con menos canciones para evitar errores y con esto la lista pierde el orden que el usuario le dio en un principio y pues la separación de interprete no se aplica correctamente.

Como puse en el primer mensaje, la lista con las categorías que el usuario desea, quedan almacenadas en un array secuencial, gracias a esto me es mas sencillo reordenar esta lista dependiendo el numero de canciones que contiene cada categoría y lo mismo al final, reordeno la lista para que quede como el usuario la pidió, por eso pienso que quizás la solución podría estar en ir guardando los interpretes que se van seleccionando en otro array.

Mi único problema es que como las canciones no se seleccionan en el orden que se van a mostrar sino dependiendo el número de canciones que tiene la categoría que le corresponde, pues la separación no queda como debe ser.

Estoy dispuesto a aclarar cualquier otro punto que quedara turbio.

Un saludo.
__________________
<? echo("1 <script> dice + que 1000 palabras"); ?> EspacioMéxico

Última edición por hieloverde; 20/12/2005 a las 13:39
  #4 (permalink)  
Antiguo 20/12/2005, 16:48
Avatar de hieloverde  
Fecha de Ingreso: julio-2005
Ubicación: México, D.F
Mensajes: 467
Antigüedad: 12 años, 5 meses
Puntos: 5
Ampliando aun más…

Por si aun no esta del todo claro en que se basa el problema al que me enfrento.

El nudo esta en el campo ‘Interprete’ de la tabla ‘melodias’ la pregunta es ¿Como debo hacer para seleccionar un registro de la tabla ‘melodias’ cuyo interprete tenga un rango de separación determinado con respecto a la ultima aparicion de ese mismo interprete?

Vean el siguiente diagrama



El diagrama ejemplifica una separacion de 5 canciones minimo y como se puede ver sin importar que la cancion 7 sea la ultima en seleccionarse, se tiene que verificar (lo que no se como) que se cumpla dicha separación.

Alguna idea?

Saludos...
__________________
<? echo("1 <script> dice + que 1000 palabras"); ?> EspacioMéxico
  #5 (permalink)  
Antiguo 21/12/2005, 05:42
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 15 años, 11 meses
Puntos: 126
Ok .. con esta explicación te recomendaría consultar en el foro de "Base de datos" .. para que te aconsejen sobre la consulta SQL más adecuada (que no va a ser sencilla seguramente).


De todas formas, creo que el lio que tienes es por un "no correcto" diseño del modelo de datos que necesitas.

Si tu usases una estructura tipo:

Autores tabla
id_autor
Nombre_autor
otros_datos_del_autor

Categorias tabla
id_categoria
nombre_categoria

melodias tabla
id_cancion
id_autor
id_categoria
nombre_cancion

En general .. más "normalización" .. sobre todo con respecto a las propiedades que en cierta manera necesitas hacer agrupaciones o consultas complejas por esos datos.

De esta forma .. con tablas "normalizadas" puedes hacer mejores consultas SQL y mas "naturales" que tu tabla "bloqueo" (que no entendí bien como funciona o que función le das).

Si quires leer sobre "normalización" y diseño optimo de tus Base de datos (orientado a Mysql) puedes ver estos tutoriales. Insisto que deberias replantear tu "modelo de datos" .. pues si bien en un "principio" para "almacenar" datos con una tabla simple y sin normalización alguna podría servirte .. esa misma sencillez es la que origina problemas en el momento que neccesitas hacer consultas SQL complejas.

Normalización
http://www.mysql-hispano.org/page.php?id=16
(en general todos los tutoriales que tienes ahí son de interes).

Para más consultas sobre el tema .. intenta usar el foro de "Base de datos" ..primero aclara el "modelo de datos" .. el SQL de las consultas complejas que necesites hacer y si tienes otros problemas que no resuelva SQL .. acude al foro de PHP para tratarlo.

Un saludo,
  #6 (permalink)  
Antiguo 21/12/2005, 18:05
Avatar de hieloverde  
Fecha de Ingreso: julio-2005
Ubicación: México, D.F
Mensajes: 467
Antigüedad: 12 años, 5 meses
Puntos: 5
Si, ya comprendo eso de la normalización, hasta el momento se que uno de sus beneficios es el no tener datos repetidos, esto que reduce el peso de la BD. Lo que todavía no entiendo (y obviamente será tema para el foro de Bases de datos) es: como con todo y normalización voy a poder seleccionar un registro que tenga un rango de separación definido?

Siendo que las condiciones de selección de dicho registro (como expuse antes) no son las convencionales.

Implementare la normalización y pues me voy al foro de bases de datos…

Gracias Cluster, U.G y a nadie mas.

Saludos
__________________
<? echo("1 <script> dice + que 1000 palabras"); ?> EspacioMéxico
  #7 (permalink)  
Antiguo 22/12/2005, 05:31
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 15 años, 11 meses
Puntos: 126
El detalle está que tu estás pensado en ese minuto según tu modelo de datos -no normalizado- por ende ... bajo tu modelo de datos pueda ser "complicado" hacer lo que pretendes ..pero "normalizado" la BD seguramente la consulta SQL a realizar es más "natural" aprovechando todas las virtudes del SQL.

(Ya veo que haz inciado tu tema en el foro de Base de datos .. será mejor continuar por allá el tema: primero encontrando el modelo de datos que más se te acomode a los datos que manejas y sus relaciones .. para posteriormente con ese modelo de datos ya normalizado ver la consulta SQL más compleja que puedas tener como el caso que planteas aquí).

Un saludo,
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 14:20.