Problema con una consulta no funciona Distinct

Iniciado por Marciano_79, 3 Abril 2016, 02:28 AM

0 Miembros y 1 Visitante están viendo este tema.

Marciano_79

 :o Ohh gracias se pasaron voy a probar de inmediato toda estas respuestas que me han entregado... mil gracias, les comento pronto los resultados.!!

Marciano_79

#11
Hola muchas gracias por responder e intentar ayudarme.... He probado hacer los ajustes que me recomiendan, pero el resultado lamentablemente sigue igual,  incluso en algunos casos aplicando los cambios, el resultado es que se desaparece algunas galerías de fotos y se mezclan todos los resultados en las diferentes categorías de forma idéntica... con estas consultas

Código (sql) [Seleccionar]

1

"SELECT DISTINCT
 galerias.IDGALERIA,
 galerias.FKCATEGORIA_ID,
 galerias.DESCRIPCION,
 galerias.NOMBRECATEGORIA,
 galerias.TITULO,
 DATE_FORMAT( galerias.FECHA_ALTA, '%d/%m/%Y' ) AS FECHA_ALTA,
 categoria.IDCATEGORIA,
 categoria.NOMBRE_CATEGORIA  
   

FROM galerias INNER JOIN categoria ON galerias.NOMBRECATEGORIA = categoria.NOMBRE_CATEGORIA
WHERE galerias.NOMBRECATEGORIA='$id'";

----------------------------------------------------------------------------------
2

"SELECT DISTINCT
 galerias.IDGALERIA,
 galerias.FKCATEGORIA_ID,
 galerias.DESCRIPCION,
 galerias.NOMBRECATEGORIA,
 galerias.TITULO,
 DATE_FORMAT( galerias.FECHA_ALTA, '%d/%m/%Y' ) AS FECHA_ALTA,
 categoria.IDCATEGORIA,
 categoria.NOMBRE_CATEGORIA  
   

FROM galerias INNER JOIN categoria ON galerias.NOMBRECATEGORIA='$id' AND categoria.NOMBRE_CATEGORIA = '$id'";


y el resultado es este: Lo que está en rojo es el valor devuelto, y lo que está en azul es como debería estar (con este resultado les muestro que no tengo solo una categoría de galerías fotográficas)

PD: deje tal cual la fecha ya que con el cambio propuesto este dejaba de mostrarse



Resumen: tengo 3 galerías Retrato, 2 galerías Moda, y 1 galería Infantil. Total 6 galerías creadas... hasta el momento solo veo 5 galerías juntas sin orden y todas aparecen de igual forma por cada pagina de cada categoría

Ahora voy a dejar el código completo ya que entremedio hay otras consultas de otras tablas que tal vez puedan estar generando conflicto...

Este es para el menú donde llamo a las categorías, y se impriman en pantalla por su nombre:

index.php

Código (sql) [Seleccionar]
<?php
include('panel/_setup.php');

$consulta =<<<SQL
SELECT DISTINCT
     IDCATEGORIA,
     NOMBRE_CATEGORIA
FROM
     categoria

INNER JOIN galerias ON categoria.IDCATEGORIA=galerias.FKCATEGORIA_ID

ORDER BY
IDCATEGORIA ASC 
 
SQL;

$filas mysqli_query($cnx$consulta);

?>


<title>Galerías</title>
<link rel="stylesheet" href="css/stylenew.css"/>
</head>

<body>
<div id="principal">
<h1>Selección de Categorias</h1>
      <?php


while( $id mysqli_fetch_assoc($filas)){
     
echo '<div>';
echo "<a href='galeria-fotografica.php?cat=$id[NOMBRE_CATEGORIA]'>$id[NOMBRE_CATEGORIA]</a>";
echo '</div>'
}
?>


</div>


Resultado: galería-fotografica.php?cat=Retrato
              galería-fotografica.php?cat=Moda
              galería-fotografica.php?cat=Infantiles


y el otro código donde esta la consulta que me da problemas:

galeria-fotografica.php

Código (php) [Seleccionar]
<?php
include('panel/_setup.php');

?>

<title>Galerías</title>
<link rel="stylesheet" href="css/stylenew.css"/>
</head>

<body>
<div id="principal">
 
<?php
    
if( isset( $_GET['gal'] ) ){
$id $_GET['gal'];
$consulta "SELECT DESCRIPCION, TITULO FROM galerias WHERE IDGALERIA='$id'";
$filas mysqli_query($cnx$consulta);
$col mysqli_fetch_assoc($filas);

echo "<h2>$col[TITULO]</h2>";
        echo 
"<p>$col[DESCRIPCION]</p>";
        echo 
'<a href="javascript:history.back(-1);" title="Ir la página anterior">VOLVER ATRAS</a>';
        echo 
'<div id="ver_galeria">';

        
$consulta ="SELECT * FROM FOTOS WHERE FKGALERIA='$id' AND ESTADO='visible' ORDER BY POSICION";
        
$filas mysqli_query($cnx$consulta);
        while( 
$col mysqli_fetch_assoc($filas)){
echo '<div>';
echo '<img src="fotos/'.$col['ARCHIVO'].'" alt="'.$col['NOMBRE'].'" />';

echo '</div>';
  }
          echo 
'</div>';   


}else{


if( isset( $_GET['cat'] ) ){  
    $id $_GET['cat'];
        
$consulta ="SELECT DISTINCT 
                         galerias.IDGALERIA,
         galerias.FKCATEGORIA_ID, 
         galerias.DESCRIPCION, 
 galerias.NOMBRECATEGORIA, 
 galerias.TITULO,
         DATE_FORMAT( galerias.FECHA_ALTA, '%d/%m/%Y' ) AS FECHA_ALTA, 
 categoria.IDCATEGORIA,
                         categoria.NOMBRE_CATEGORIA    
     

FROM galerias INNER JOIN categoria ON galerias.NOMBRECATEGORIA='
$id' AND categoria.NOMBRE_CATEGORIA = '$id'";
         

$filas mysqli_query($cnx$consulta);
$columna mysqli_fetch_assoc($filas);
echo "<h1>Galerías $columna[NOMBRECATEGORIA]</h1>";
    
}
echo '<div id="listado">';
while( $columna mysqli_fetch_assoc($filas)){
  $id $columna['IDGALERIA'];
  $subconsulta "SELECT ARCHIVO FROM fotos WHERE FKGALERIA='$id' AND ESTADO='visible' ORDER BY RAND() LIMIT 1";
  $filas2 mysqli_query($cnx$subconsulta);
  $datos mysqli_fetch_assoc($filas2);
  
  $nombre_archivo $datos['ARCHIVO'];
  
  echo '<div>';  
  echo "<h2>$columna[TITULO]</h2>";
  echo "<div>$columna[FECHA_ALTA]</div>";
  if( $nombre_archivo != null ){
  echo "<img src='fotos/$nombre_archivo' alt='Preview de la galeria' />";
  }
  echo "<p>"nl2br$columna['DESCRIPCION'])."</p>";
  echo "<a href='galeria-fotografica.php?gal=$columna[IDGALERIA]'>VER GALERIA</a>";
  echo '</div>';
  }
  echo '</div>';



    }

 

?>



</div>


y la info de mis tablas:

Estructura de tabla para la tabla categoria


|Columna|Tipo|Nulo|Predeterminado

IDCATEGORIA|tinyint(25)|No
NOMBRE_CATEGORIA varchar(100)|Sí NULL

Volcado de datos para la tabla categoria


|1|Retrato
|2|Moda
|3|Infantiles



Estructura de tabla para la tabla galerias


|Columna|Tipo|Nulo|Predeterminado

IDGALERIA tinyint(25) No
TITULO varchar(100) Sí NULL
FECHA_ALTA datetime Sí NULL
DESCRIPCION text Sí NULL
NOMBRECATEGORIA varchar(100) Sí NULL
FKCATEGORIA_ID tinyint(20) Sí NULL

Volcado de datos para la tabla galerias

|1|Retrato-1| 2016-03-30 14:54:27 |bla,bla,bla |Retrato  |1
|2|Infantiles-1 |2016-03-30 14:55:22 |bla,bla,bla,bla,bla,bla |Infantiles  |3
|3|Retrato-2|2016-03-30 14:57:18|bjbbbk|Retrato |1
|4|Moda-1|2016-03-30 14:59:03|hvv,vgvhjvjhv,j|Moda |2
|5|Moda-2|2016-03-30 14:59:55|vhvhv|Moda |2
|6|Retrato-3|2016-03-30 15:00:35|cttdtftdtft|Retrato |1


dejo tambien la de tabla fotos (que no creo que sea de importancia, pero porsiacaso..



Estructura de tabla para la tabla fotos


|Columna|Tipo|Nulo|Predeterminado

|IDFOTO |int(25) |No|
|NOMBRE|varchar(100)|Sí|NULL
|ARCHIVO|varchar(100)|Sí|NULL
|POSICION|tinyint(3)|Sí|NULL
|ESTADO|enum('visible', 'invisible')|Sí|NULL
|FKGALERIA|tinyint(3)|Sí|NULL

Volcado de datos para la tabla fotos

|1|gdrgdrg |6ebbdb026d9c9.jpg|1|visible|1
|2|hajhajhjsh |fe4ba595921ffbbdd8.jpg|2|visible|1
|3|ajajskanka |d4cc19c8fbfdbe.jpg|1|visible|2
|4|nnjnjnjn |3d52dc1b7b.jpg|2|visible|2
|5|jojojojo |ab5788e01f4.jpg|1|visible|3
|6|knknknk |430ca7182b3.jpg|2|visible|3
|7|ububu |ad5d51bea35ff.jpg|1|visible|4
|8|addwbdb |b93635e8e092.jpg|2|visible|4
|9|sincinansn|6ba1b35d71d4d519748e9aa8b42c07f1.jpg|1|visible|5
|10|scknakcnkasnc|4dee3e3a41c53fd82de1b3227d1df372.jpg|2|visible|5
|11|sjcjsajcbjasbcjab|bf681c114a1f857ab8883143f4660246.jpg|1|visible|6
|12|scsjcnjasncj|629eef20bc75c576e931cc181296a3d7.jpg|2|visible|6


Espero estos datos puedan aportar mayor ayuda... espero con ansias sus respuestas.. muchas gracias de verdad.!

MinusFour

#12
Siento que la pregunta ha cambiado totalmente. Pero lo que estoy viendo es que tus campo IDGALERIA, TITULO, DESCRIPCION, etc son todos diferentes, lo cual explica tus hileras repetidas en la primera imagen que pusiste. La última imagen que has puesto es un simple JOIN.

Código (sql) [Seleccionar]

SELECT categoria.IDCATEGORIA,
      categoria.NOMBRECATEGORIA,
      galerias.TITULO,
      DATE_FORMAT( galerias.FECHA_ALTA, '%d/%m/%Y' ) AS FECHA,
      galerias.DESCRIPCION,
      fotos.ARCHIVO
FROM galerias
INNER JOIN categoria ON categoria.IDCATEGORIA = galerias.FKCATEGORIA_ID
INNER JOIN fotos ON galerias.IDGALERIA = fotos.FKGALERIA


Puedes restringir los resultados al titulo de una categoria con WHERE:

Código (SQL) [Seleccionar]

... WHERE categoria.NOMBRECATEGORIA = '$id'


Esto debe mostrarte 6 resultados de acuerdo a lo que has puesto:

Citar|1|Retrato-1| 2016-03-30 14:54:27 |bla,bla,bla |Retrato  |1
|2|Infantiles-1 |2016-03-30 14:55:22 |bla,bla,bla,bla,bla,bla |Infantiles  |3
|3|Retrato-2|2016-03-30 14:57:18|bjbbbk|Retrato |1
|4|Moda-1|2016-03-30 14:59:03|hvv,vgvhjvjhv,j|Moda |2
|5|Moda-2|2016-03-30 14:59:55|vhvhv|Moda |2
|6|Retrato-3|2016-03-30 15:00:35|cttdtftdtft|Retrato |1

Sin embargo en tu tabla tienes 8 registros, aparecen Moda-3 e Infantiles-2. Para la información que tienes la consulta que he puesto debe funcionar. Pero las imagenes que pones no concuerda exactamente con tu información. Si quieres solucionar un problema real, vas a tener que plantear el problema real con información real. Nada de hipotéticas por favor, que ya van varias personas que intentan solucionar problemas ficticios en este tema y no es justo para ellos.

Otros detalles que puedo ver en tu script de PHP:

Realizas subconsultas separadas cuando pueden ser escritas bajo una consulta y estás saltandote el primer registro para obtener las cabeceras de tu apartado.

Código (php) [Seleccionar]

$filas = mysqli_query($cnx, $consulta);
$columna = mysqli_fetch_assoc($filas);
echo "<h1>Galerías $columna[NOMBRECATEGORIA]</h1>";

}
echo '<div id="listado">';
while( $columna = mysqli_fetch_assoc($filas)){
 $id = $columna['IDGALERIA'];


Cuando llamas a mysqli_fetch_assoc, lees la primea fila y el puntero de $filas cambia a la siguiente fila. Por lo que cuando entras en el while, empiezas a imprimir desde la segunda fila. Básicamente pierdes la información de la primera fila.

Si vas a usar la consulta que te he puesto (que hace el inner join con la tabla de fotos tambien) te sugiero que agregues a los campos selecionados el campo de ESTADO. Verificas en cada hilera si el estado es visible o no (muy parecido a como lo tienes ahora).

Marciano_79

Hola gracias por responder.. tienes toda la razón, con respecto a resultados ficticios, el tema es que había eliminado esos registros la noche anterior y al volcar los datos de las tablas hoy, me entrego lógicamente los nuevos, no me di cuenta.. lo siento mucho, para nada es mi intención hacer perder el tiempo a nadie.. de verdad mil disculpas.! ahora voy a intentar hacer los cambios que me planteas, y ademas como dije al comienzo del post "yo no soy programador" y haré mi mayor esfuerzo por comprender bien todo lo que me dices.. muchas gracias.!!  :)

Marciano_79

Amigo, gracias por tu ayuda, pero no sé cómo agregar el campo ESTADO en especial, el verificar si el estado es visible o no, ya la cabeza se me parte... quiero hacerlo como me indicas tu, todo en una misma consulta, pero ya no sé cómo y la ignorancia y frustración ya se apodero de mi... en este script, implemente la consulta que me entregaste...

Código (php) [Seleccionar]
<?php
if( isset( 
$_GET['cat'] ) ){  
    $id $_GET['cat'];
        
$consulta ="SELECT DISTINCT
                       categoria.IDCATEGORIA,
       galerias.IDGALERIA,
                       galerias.NOMBRECATEGORIA,
                       galerias.TITULO,
                       DATE_FORMAT( galerias.FECHA_ALTA, '%d/%m/%Y' ) AS FECHA,    
       galerias.DESCRIPCION,
       fotos.ARCHIVO,
       fotos.ESTADO
FROM galerias
INNER JOIN categoria ON categoria.IDCATEGORIA = galerias.FKCATEGORIA_ID
INNER JOIN fotos ON galerias.IDGALERIA = fotos.FKGALERIA
WHERE galerias.NOMBRECATEGORIA = '
$id'";   
         

$filas mysqli_query($cnx$consulta);
$columna mysqli_fetch_assoc($filas);
echo "<h1>Galerías $columna[NOMBRECATEGORIA]</h1>";
    
}
echo '<div id="listado">';
while( $columna mysqli_fetch_assoc($filas)){
  $id $columna['IDGALERIA'];
  
  $datos mysqli_fetch_assoc($filas);
  
  $nombre_archivo $datos['ARCHIVO'];
  
  echo '<div>';  
  echo "<h2>$columna[TITULO]</h2>";
  echo "<div>$columna[FECHA]</div>";
  if( $nombre_archivo != null ){
  echo "<img src='fotos/$nombre_archivo' alt='Preview de la galeria' />";
  }
  echo "<p>"nl2br$columna['DESCRIPCION'])."</p>";
  echo "<a href='galeria-fotografica.php?gal=$columna[IDGALERIA]'>VER GALERIA</a>";
  echo '</div>';
  }
  echo '</div>';



    }

 

?>




Gracias a tu consulta, los resultados son muy buenos, me muestra los 6 registros que tengo, en las categoría retrato tengo las 3 galerías, en categoría moda, tengo las 2 galerías  y en categoría infantil aparece la única que tengo.. en la imagen se puede apreciar mejor:



Porfavor puedes ayudarme a modificar bien el código para que se vea los registros faltantes, en este caso ARCHIVO. que pertenecía a la subconsulta
"SELECT ARCHIVO FROM fotos WHERE FKGALERIA='$id' AND ESTADO='visible' ORDER BY RAND() LIMIT 1";

Ya que realmente no sé cómo hacerlo, porfavor.!! Mil gracias de nuevo..


HdM

Creo que esta consulta se ajustaría a tu necesidad:

Código (php) [Seleccionar]
SELECT DISTINCT
                       categoria.IDCATEGORIA,
       galerias.IDGALERIA,
                       galerias.NOMBRECATEGORIA,
                       galerias.TITULO,
                       DATE_FORMAT( galerias.FECHA_ALTA, '%d/%m/%Y' ) AS FECHA,    
       galerias.DESCRIPCION,
      IFNULL((SELECT fotos.ARCHIVO FROM fotos WHERE galerias.IDGALERIA = fotos.FKGALERIA AND ESTADO='visible' ORDER BY RAND()  LIMIT 1),'NO APARECE') AS ARCHIVO
FROM
                     galerias INNER JOIN categoria ON categoria.IDCATEGORIA = galerias.FKCATEGORIA_ID
WHERE
                     galerias.NOMBRECATEGORIA = '$id'

- Nice to see you again -

MinusFour

¿Cada galería tiene por lo menos una foto verdad? No me había dado percatado de las otras limitantes de tu subconsulta, pero en teoría deberías poder realizar un LEFT JOIN así:

Código (SQL) [Seleccionar]

SELECT categoria.IDCATEGORIA,
       categoria.NOMBRECATEGORIA,
       galerias.TITULO,
       DATE_FORMAT( galerias.FECHA_ALTA, '%d/%m/%Y' ) AS FECHA,
       galerias.DESCRIPCION,
       fotos.ARCHIVO
FROM galerias
INNER JOIN categoria ON categoria.IDCATEGORIA = galerias.FKCATEGORIA_ID
LEFT JOIN
    (SELECT * FROM (
       SELECT FKGALERIA,
              ARCHIVO
       FROM fotos
       WHERE estado = 'visible'
       ORDER BY RAND()
    ) as tmp
    GROUP BY tmp.FKGALERIA) as fotos
ON galerias.IDGALERIA = fotos.FKGALERIA
WHERE categoria.NOMBRECATEGORIA = '$id'


Los mismos detalles aplican a tu código. El LEFT JOIN considera que puede o no haber un valor que intersecta con la tabla de fotos. Todavía tienes el detalle que te mencione en tu código. No hace falta si quiera que recojas el valor directamente de la consulta porque sabes bien que el nombre de la categoría es igual a tu variable $_GET['cat'].

La consulta tiene algunos otros detalles como el agrupamiento de columnas no agregadas... En MySQL 5.7 esto probablemente no funcione. La consulta también está expuesta a inyecciones SQL.

Marciano_79

Muchas gracias HdM y MinusFour para mi es impagable vuestra ayuda... y si MinusFour cada galería tiene una imagen como tumb que la toma al azar de su propio álbum :) verificare las consultas ahora mismo.... aun así me surge la siguiente duda: "es necesario que al aplicar esta consulta anidada (si es que se dice así) la ejecución de este tipo de sentencias requiere la utilización de la función: mysqli_multi_query($conexion,sentencia_multiple) o no"?

Gracias nuevamente..

MinusFour

Hasta donde yo se, esa función es para lanzar multiples queries al servidor. E.g.:

Código (sql) [Seleccionar]

SELECT * FROM A; -- Query 1
SELECT * FROM B; -- Query 2

Marciano_79

Ok, amigos, probé las dos consulta que me dieron, pero se hacia un caos en todos los registros, solo aparecían una galería y sin imágenes ni nada, en otras con imágenes pero faltando galerías, y otras sin nada  de nada...

Ahora al dejar la propuesta de la penúltima consulta que me entregaste, es la que mejor funciona, de hecho ahora con unas modificaciones que hice se pueden ver todas las galerías, con sus respectivas categorías y sus fotos "tumb" lo único que faltaría es el RAND para que los tumb o fotos de las galerías cambien de forma aleatoria.. así deje el código:

Código (php) [Seleccionar]
if( isset( $_GET['cat'] ) ){ 
    $id = $_GET['cat'];
        $consulta ="SELECT DISTINCT
                       categoria.IDCATEGORIA,
       galerias.IDGALERIA,
                       galerias.NOMBRECATEGORIA,
                       galerias.TITULO,
                       DATE_FORMAT( galerias.FECHA_ALTA, '%d/%m/%Y' ) AS FECHA,    
       galerias.DESCRIPCION,
       fotos.ARCHIVO,
       fotos.ESTADO
       FROM galerias
INNER JOIN categoria ON categoria.IDCATEGORIA = galerias.FKCATEGORIA_ID
INNER JOIN fotos ON galerias.IDGALERIA = fotos.FKGALERIA

WHERE galerias.NOMBRECATEGORIA = '$id'";   
         

$filas = mysqli_query($cnx, $consulta);
$columna = mysqli_fetch_assoc($filas);
echo "<h1>Galerías $columna[NOMBRECATEGORIA]</h1>";

}
echo '<div id="listado">';
$filas = mysqli_query($cnx, $consulta);
while( $columna = mysqli_fetch_assoc($filas)){
 
  $id = $columna['IDGALERIA'];

  $datos = mysqli_fetch_assoc($filas);

  $nombre_archivo = $datos['ARCHIVO'];

  echo '<div>'; 
  echo "<h2>$columna[TITULO]</h2>";
  echo "<div>$columna[FECHA]</div>";
  if( $nombre_archivo != null ){
  echo "<img src='fotos/$nombre_archivo' alt='Preview de la galeria' />";
  }
  echo "<p>". nl2br( $columna['DESCRIPCION'])."</p>";
  echo "<a href='galeria-fotografica.php?gal=$columna[IDGALERIA]'>VER GALERIA</a>";
  echo '</div>';
  }
  echo '</div>';



    }


Que opinan?