traer repetidos registros ordenar mostrar eliminar ejemplos duplicados descendente consultas agrupar mysql sql-order-by

repetidos - MySQL-Ordenar por category_id intenta evitar tener duplicados cerca uno del otro



select mysql (5)

Por favor ten paciencia con mi inglés.

Tengo una mesa como esta,

id | category_id | product_id ----------------------------------- 1 | 1 | 1 2 | 1 | 2 3 | 2 | 1 4 | 2 | 3 5 | 1 | 4 6 | 3 | 5

Quiero que la salida sea,

id | category_id | product_id ---------------------------------- 1 | 1 | 1 3 | 2 | 1 6 | 3 | 5 2 | 1 | 2 4 | 2 | 3 5 | 1 | 4

Entonces, en resumen, lo que necesito es que el category_id se ordene de modo que se repita en ciclos como 1, 2, 3, 1, 2, 3, ... etc.


... trata de evitar tener duplicados cerca uno del otro

Bueno esta bien. La solución más sencilla que puedo encontrar es un GROUP BY ''product_id'' ORDER BY ''category_id'' . Esto haría que su mesa se vea así:

id | category_id | product_id ---------------------------------- 1 | 1 | 1 3 | 2 | 1 2 | 1 | 2 4 | 2 | 3 5 | 1 | 4 6 | 3 | 5

Supongo que "category_id se debe ordenar para que se repita en ciclos" es una traducción de "No quiero duplicados cerca uno del otro".

Si tuviera tres categorías en el producto uno y en el producto dos, se agruparían (1,1,1,2,2,2) pero las categorías serían ordenadas numéricamente (1,2,3,1,2,3) . No es una solución perfecta para lo que quieres, pero es una solución simple que parece darte lo que necesitas.

Cualquier piratería complicada en su consulta solo ralentizará la consulta. Si bien puede que no sea un problema ahora, podría ser un gran problema si tiene muchos registros.


Aquí está mi solución:

SET @rank=-1; SET @prior_category=null; SELECT @cycle_length:=COUNT(distinct category_id) FROM table1; SELECT id, category_id, product_id FROM (SELECT @rank:=CASE WHEN @prior_category!=category_id THEN 0 ELSE @rank+1 END AS rank, @prior_category:=category_id AS prior_category_id, id, category_id, product_id FROM table1 ORDER BY category_id) AS extended_table1 ORDER BY rank*@cycle_length + category_id, id;

Demostración aquí: http://sqlfiddle.com/#!9/5bce3/37


Aquí hay una consulta que le da ese resultado:

SELECT p1.* FROM `product` p1 JOIN `product` p2 ON p2.category_id = p1.category_id AND p2.id <= p1.id GROUP BY p1.id ORDER BY COUNT(*),category_id;

Donde el product es tu mesa.

Ver DEMO AQUÍ


En serio, debe pensar en reestructurar su tabla, necesita agregar un campo temporal, lo que categorizaría la categoría categoría y luego ordenar por ese campo remp. Mi sugerencia es a continuación.

CREATE TABLE Test1 ( id int, t_category int, category_id int, Product_id int);

INSERT INTO Test1 ( id , t_category , category_id , product_id ) VALUES (1,1,1,1), (2,2,1,2), (3,1,2,1), (4,2,2, 3), (5,3,1,4), (6,1,3,5);

SELECCIONE category_id, product_id FROM Test1 orden por t_category, category_id


//Get largest category_id value $sql = "SELECT category_id FROM table ORDER BY category_id DESC LIMIT 1"; $result = $conn->query($sql); $row = $result->fetch_assoc(); $maxCatId = $row[''category_id'']; //Query for every possible category_id $resultsArray = array(); for ($i = 1; $i <= $maxCatId; $i++) { $sql = "SELECT * FROM table WHERE category_id = " . $i; $resultsArray[] = $conn->query($sql); } //As long as $resultsArray is not empty while ($resultsArray) { foreach ($resultsArray as $index => $res) { if ($row = $res->fetch_assoc()) { echo $row[''id''] . '' '' . $row[''category_id''] . '' '' . $row[''product_id'']; } else { unset($resultsArray[$index]); } } }

Primero obtenga el valor más grande para category_id , luego pase de 1 a max category_id y almacene todos los objetos de resultados en $resultsArray . Ahora use foreach dentro de un tiempo para obtener los resultados.

El if else inside foreach emite un registro o elimina un objeto de resultado de $resultsArray si no tiene más registros en él. Cuando $resultsArray está completamente vacío, mientras que el bucle se rompe.