Vi la siguiente consulta de MySQL que usa tanto DISTINCT como GROUP BY juntos:

SELECT DISTINCT user_id, post_id, post_content FROM some_table GROUP BY post_id, user_id HAVING post_content LIKE "%abc%"; 

Aquí hay un escenario para acompañar la consulta: cada usuario tiene una identificación única, user_id, y puede realizar varias publicaciones que se identifican con una identificación única, post_id. Cada publicación contendría algún texto.

Encontré esto confuso (después de venir de bases de datos de Oracle) y tenía las siguientes preguntas:

  1. ¿Cuál es el significado de usar GROUP BY sin hacer ninguna agregación?
  2. ¿Cuál es la importancia de cambiar el orden de las columnas en SELECT y en GROUP BY ?
  3. ¿Cuál es el significado de omitir la tercera columna de GROUP BY?
  4. ¿Por qué DISTINCT usado junto con GROUP BY? ¿Se ejecuta una operación distinta después de que se hayan realizado todas las agrupaciones en el resultado final o antes?

Comentarios

  • Elemento 2: No hay significado. El GROUP BY no importa en absoluto (excepto que en las versiones anteriores, implicaba el mismo ORDER BY. El SELECT el orden solo importa en la disposición de las columnas en la salida.

Respuesta

ad 1) Antiguas bases de datos mysql y cuando desactivas ONLY_FULL_GROUP_BY , puedes realizar esta consulta y si los post_content son todos iguales, notarás que mysql devuelve un valor aleatorio no determinista .

anuncio 2) ninguno

anuncio 3) programación diferida y se produce un error cuando habilita ONLY_FULL_GROUP_BY

ad 4) No, mostraría todos los post_content que están conectados a user_id, post_id similar a addind post_content al grupo por

Como Strawberry ya dijo, esta consulta no tiene algún sentido

Responder

La increíble capacidad de permitir grupos parciales en versiones anteriores de MyS QL, tiene que ser uno de los principales competidores para la mayoría de las confusiones causadas en la industria de TI.

Dada la tabla:

CREATE TABLE t ( x int not null primary key , y int not null ); INSERT INTO t (x,y) VALUES (1,1),(1,2); 

La declaración

SELECT x, y FROM t GROUP BY x 

podría significar (1,1) o (1,2) y MySQL devolvería aleatoriamente uno de estos. DISTINCT no importa en este caso, el resultado sigue siendo in-determinista.

SQL92 requería que todas las columnas de la cláusula select (excepto las columnas agregadas y las constantes) formen parte de la cláusula GROUP BY.

SQL99 aflojó un poco esta restricción y nos permitió omitir columnas del GROUP BY que son funcionalmente dependientes de las columnas restantes. Es decir,

CREATE TABLE t ( x int not null primary key , y int not null ); SELECT x, y FROM t GROUP by x 

sería válido ya que y es f.d. de x

Sorprendentemente (para mí), la versión posterior de MySQL es la mejor en su clase cuando se trata de implementar la versión SQL99. No lo he comprobado últimamente, pero cuando lo hice, MySQL manejó bien escenarios bastante complicados, mientras que PostgreSQL solo manejó los triviales.

Para responder a sus preguntas

1)

SELECT x, y FROM t GROUP BY x, y 

significa que la combinación de x, y es un grupo. En todas las situaciones posibles, puedo pensar que esto es lo mismo que:

SELECT DISTINCT x, y FROM t 

Dado que se evalúan lógicamente en diferentes momentos, puede haber algún caso de esquina en el que realmente difieran (aunque no puedo pensar en uno)

2) Ninguno , en este sentido son un conjunto de columnas, por lo que no hay orden

3) Ver arriba.

4) El orden lógico de evaluación de una consulta SQL es:

FROM, JOIN WHERE GROUP BY HAVING SELECT DISTINCT ORDER BY FETCH FIRST 

por lo que se supone que GROUP BY debe evaluarse antes que DISTINCT. No puedo pensar en una situación en la que esto importe.

En su consulta Sospecho que alguien obtuvo resultados confusos e intentó obtener otro resultado usando DISTINCT. Probablemente tuvieron suerte (o mala suerte) de obtener el resultado que esperado, por lo que el DISTINCT se quedó. Sin embargo, el error sigue ahí

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *