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

Hola a todos, favor chicos.. estoy hace un mes tratando de poder solucionar una consulta que me está entregando registros duplicados, en algunos casos hasta triplicados... trabajo con MySqli y la verdad es que he probado de tantas formas que ya no se que más hacer... no soy programador, por ello si me explico mal favor tener paciencia vale? estas son mis tablas..

Tabla categoria:
IDCATEGORIA
NOMBRE_CATEGORIA

Tabla galerias:
IDGALERIAS
TITULO
DESCRIPCION
FECHA_ALTA
NOMBRECATEGORIA
FKCATEGORIA_ID

mi codigo:

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

FROM galerias a INNER JOIN categoria b ON a.NOMBRECATEGORIA='$id'";
       

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


dejo una imagen del resultado devuelto actualmente.. la tabla que se ve en rojo es lo que obtengo y la que esta en azul es lo que realmente quiero que se visualice..



Esto es el resultado de la categoría retrato, pero ocurre también en las distintas otras categorías que tengo, moda, infantiles etc... todas entregan el mismo resultado... Porfavor alguien amable me pueda ayudar.. de ante mano muchas gracias.!!

engel lex

El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.

Marciano_79


engel lex

ya que estás usando join lo recomendable es usar el formato tabla.campo no es necesario que redeclares como a y b, hazlo directo

Código (sql) [Seleccionar]
SELECT DISTINCT
                  (galerias.IDGALERIA),
                  galerias.TITULO,
                  galerias.DESCRIPCION,
                  categoria.NOMBRECATEGORIA,
                  categoria.FKCATEGORIA_ID,
                  DATE_FORMAT( galerias.FECHA_ALTA, '%d/%m/%Y' ) AS galeria.FECHA_ALTA,
                  categoria.IDCATEGORIA,
                  categoria.NOMBRE_CATEGORIA 

               FROM galerias INNER JOIN categoria ON galerias.NOMBRECATEGORIA=catgoria.'$id'


o como sea tu orden


El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.

Marciano_79

#4
Gracias por tu tiempo y disponibilidad, pero la verdad esto no quiere funcionar, probé así como me dices y nada..  

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

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


me sale esto: Warning: mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, boolean given in C:\xampp\htdocs\prueba\galeria-fotografica.php on line 54

sinceramente me tiene mal la situación... que crees que pueda hacer? Gracias por tu ayuda..

Marciano_79

cambiando la consulta o forma seria opción?

HdM

Deberías enlazar correctamente las dos tablas en la consulta ¿no?

IDCATEGORIA <-> FKCATEGORIA_ID

- Nice to see you again -

MinusFour

Por lo general unes las columnas con ON y dejas las restricciones en WHERE pero esto puede funcionar. Claro que no debería ser:

Código (SQL) [Seleccionar]

... ON galerias.NOMBRECATEGORIA=categoria.'$id'


Sino:

Código (SQL) [Seleccionar]

... ON galerias.NOMBRECATEGORIA='$id'


No es necesario usar nombres de tabla en este caso porque no hay una ambigüedad en las tablas (o vistas parciales), si tuvieras tablas con campos que usan el mismo nombre entonces si necesitas especificar el nombre con la tabla (aunque en mi opinión es más claro ver de donde salen los campos en la consulta).

El alias de la función DATE_FORMAT no necesita especificarse un campo de la tabla:

Código (sql) [Seleccionar]

DATE_FORMAT( galerias.FECHA_ALTA, '%d/%m/%Y' ) AS FECHA_ALTA


DISTINCT no es una función (no es necesario los paréntesis).

En fin, nada de esto explica porque obtuviste esos resultados anteriormente, la consulta que muestras debería regresar esas hileras para los campos que aparecen en tu documento de excel, pero en tu documento no estás mostrando los valores de las otras columnas (son 8 columnas las que seleccionas en tu consulta, tu documento de excel solo muestra 5).

HdM

Para mi, el que los campos que indiqué no estén enlazados en la consulta, si explica los resultados "erróneos" obtenidos. ¿Cómo sabe el motor qué registros de una y otra tabla extraer, si ambas no están enlazadas en la query en cuestión?

En este caso concreto, sabe que tiene que extraer los registros de la tabla galerias por:

Código (php) [Seleccionar]
ON galerias.NOMBRECATEGORIA='$id'

pero no de la tabla categoria (y entiendo que por tanto sacará todos los registros de la misma. De ahí la repetición de los mismos).

Justo lo contrario sucedería si en vez del ON anterior, fuese:

Código (php) [Seleccionar]
ON categoria.NOMBRE_CATEGORIA='$id'

extraería los registros correctos de la tabla categoría y todos los registros de la tabla galerías.

Por tanto, consultas tales como:

Código (sql) [Seleccionar]
SELECT
       DISTINCT  galerias.IDGALERIA,
       galerias.TITULO,
       galerias.DESCRIPCION,
       galerias.NOMBRECATEGORIA,
       galerias.FKCATEGORIA_ID,
       DATE_FORMAT( galerias.FECHA_ALTA, '%d/%m/%Y' ),
       categoria.IDCATEGORIA,
       categoria.NOMBRE_CATEGORIA
FROM
      galerias INNER JOIN categoria ON galerias.NOMBRECATEGORIA = categoria.NOMBRE_CATEGORIA 
      AND galerias.NOMBRECATEGORIA = '$id';


Código (sql) [Seleccionar]
SELECT
       DISTINCT  galerias.IDGALERIA,
       galerias.TITULO,
       galerias.DESCRIPCION,
       galerias.NOMBRECATEGORIA,
       galerias.FKCATEGORIA_ID,
       DATE_FORMAT( galerias.FECHA_ALTA, '%d/%m/%Y' ),
       categoria.IDCATEGORIA,
       categoria.NOMBRE_CATEGORIA
FROM
        galerias INNER JOIN categoria ON galerias.NOMBRECATEGORIA = categoria.NOMBRE_CATEGORIA
WHERE
        galerias.NOMBRECATEGORIA = '$id';


Código (sql) [Seleccionar]
SELECT
       DISTINCT  galerias.IDGALERIA,
       galerias.TITULO,
       galerias.DESCRIPCION,
       galerias.NOMBRECATEGORIA,
       galerias.FKCATEGORIA_ID,
       DATE_FORMAT( galerias.FECHA_ALTA, '%d/%m/%Y' ),
       categoria.IDCATEGORIA,
       categoria.NOMBRE_CATEGORIA
FROM
       galerias, categoria
WHERE
       galerias.NOMBRECATEGORIA = categoria.NOMBRE_CATEGORIA 
       AND galerias.NOMBRECATEGORIA = '$id';


y equivalentes, mostrarán los resultados deseados.


- Nice to see you again -

MinusFour

#9
Ah cierto, de la primera forma se realiza un producto cruzado entre $id y todos las hileras de categoria, aunque en su ejemplo solo tiene una categoría al parecer. También deberías poder hacer:

Código (sql) [Seleccionar]

   ON galerias.NOMBRECATEGORIA = '$id' AND categoria.NOMBRE_CATEGORIA = '$id'


Aunque en mi opinión es mejor si vas por la segunda proposición de HdM.

Esto todavía no explica porque tienes registros duplicados en tus resultados. Si tu tienes resultados tal cuales lo has mostrado en tu imagen, no deberías tener resultados duplicados.

DISTINCT opera sobre las hileras de tus resultados. Supongamos que tienes 2 tablas A y B con un solo campo.



A | B
--------
1 | 2
  | 3
  | 4
  | 5
  | 6


Si tu haces:

Código (sql) [Seleccionar]

SELECT * FROM A INNER JOIN B -- INNER JOIN se vuelve CROSS JOIN


Acabas con una tabla asi:


-------
|1 | 2|
-------
|1 | 3|
-------
|1 | 4|
-------
|1 | 5|
-------
|1 | 6|
-------


Si tu usas DISTINCT aquí, acabarás con la misma tabla, porque cada uno de los registros de la tabla es único. Si tuvieras una tabla así:




A | B
--------
1 | 1
  | 1
  | 1
  | 1
  | 1


E hicieras la misma consulta tendrías:


-------
|1 | 1|
-------
|1 | 1|
-------
|1 | 1|
-------
|1 | 1|
-------
|1 | 1|
-------


Si usarás DISTINCT para los resultados de esta consulta acabarías con:


-------
|1 | 1|
-------


Por eso mismo dije que lo mencionado hasta ahorita no explica el resultado de tu tabla, porque los resultados que muestras son idénticos y reducibles por DISTINCT. La única forma para la cual tendrías estos valores duplicados sería que los otros valores de las columnas que no muestras son diferentes.

Por ejemplo, veo ahí un campo IDGALERIA que no estoy seguro si sea o no único. Si el campo es un identificador que se auto incrementa por cada registro seleccionar ese campo va a producir que cada hilera sea diferente (por ende DISTINCT no los descarta).