Consulta SQL, seleccionando 5 más recientes en cada grupo

Tengo esta table

CREATE TABLE `codes` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `language_id` int(11) unsigned NOT NULL, `title` varchar(60) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, `time_posted` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 

language_id se refiere a qué idioma está el logging. Lo que me gustaría hacer es recuperar una list de los cinco loggings más recientes (ORDER BY time_posted DESC LIMIT 5) en cada language_id . Podría hacer esto en un bucle dentro de PHP con una cantidad de consultas SQL diferentes, pero creo que hay una manera más simple.

Tengo que conseguir un libro sobre SQL, jaja.

Gracias.

Así es como resuelvo este tipo de consulta "N superior por grupo" en MySQL:

 SELECT c1.* FROM codes c1 LEFT OUTER JOIN codes c2 ON (c1.language_id = c2.language_id AND c1.time_posted < c2.time_posted) GROUP BY c1.id HAVING COUNT(*) < 5; 

Consulte también " ¿Cómo selecciono varios elementos de cada grupo en una consulta de MySQL? "

Aquí hay una gran solución que acabo de encontrar.

Seleccione las N primeras filas para cada grupo Arnie Rowland, 13 de marzo de 2008

Hay Múltiples Filas para cada Categoría, y existe el deseo de SELECCIONAR SOLAMENTE las dos (2) Filas SUPERIORES por Categoría por Precio. Por ejemplo, a partir de los siguientes datos:

 RowID Category ID Description Price 1 Pot A1 Small Saucepan 21.50 2 Pot A2 1 Qt Saucepan 29.95 3 Pot A3 1.5 Qt Saucepan 33.95 4 Pot A4 Double Boiler 39.50 5 Pot A5 Stewpot 49.50 6 Pot A6 Pressure Cooker 79.95 7 Pan B1 8" Pie 6.95 8 Pan B2 8" Sq Cake 7.50 9 Pan B3 Bundt Cake 12.50 10 Pan B4 9x12 Brownie 7.95 11 Bowl C1 Lg Mixing 27.50 12 Bowl C2 Sm Mixing 17.50 13 Tools T1 14" Spatula 9.95 

El resultado deseado es:

 RowID Category ID Description Price 11 Bowl C1 Lg Mixing 27.50 12 Bowl C2 Sm Mixing 17.50 9 Pan B3 Bundt Cake 12.50 10 Pan B4 9x12 Brownie 7.95 6 Pot A6 Pressure Cooker 79.95 5 Pot A5 Stewpot 49.50 13 Tools T1 14" Spatula 9.95 

Hay varios methods para lograr la salida deseada. Esta demostración proporciona una Solución para SQL Server 2005 / SQL Server 2008, y luego una Solución para SQL Server 2000.

Crear datos de muestra para ambas soluciones

 -- Suppress data loading messages SET NOCOUNT ON -- Create Sample Data using a Table Variable DECLARE @MyTable table ( RowID int IDENTITY, Category varchar(5), [ID] varchar(5), [Description] varchar(25), Price decimal(10,2) ) -- Load Sample Data INSERT INTO @MyTable VALUES ( 'Pot', 'A1', 'Small Saucepan', 21.50 ) INSERT INTO @MyTable VALUES ( 'Pot', 'A2', '1 Qt Saucepan', 29.95 ) INSERT INTO @MyTable VALUES ( 'Pot', 'A3', '1.5 Qt Saucepan', 33.95 ) INSERT INTO @MyTable VALUES ( 'Pot', 'A4', 'Double Boiler', 39.50 ) INSERT INTO @MyTable VALUES ( 'Pot', 'A5', 'Stewpot', 49.50 ) INSERT INTO @MyTable VALUES ( 'Pot', 'A6', 'Pressure Cooker', 79.95 ) INSERT INTO @MyTable VALUES ( 'Pan', 'B1', '8"" Pie', 6.95 ) INSERT INTO @MyTable VALUES ( 'Pan', 'B2', '8"" Sq Cake', 7.50 ) INSERT INTO @MyTable VALUES ( 'Pan', 'B3', 'Bundt Cake', 12.50 ) INSERT INTO @MyTable VALUES ( 'Pan', 'B4', '9x12 Brownie', 7.95 ) INSERT INTO @MyTable VALUES ( 'Bowl', 'C1', 'Lg Mixing', 27.50 ) INSERT INTO @MyTable VALUES ( 'Bowl', 'C2', 'Sm Mixing', 17.50 ) INSERT INTO @MyTable VALUES ( 'Tools', 'T1', '14"" Spatula', 9.95 ) Return to Top 

Solución SQL Server 2005 / SQL Server 2008

 --Query to Retrieve Desinetworking Data SELECT RowID, Category, [ID], [Description], Price FROM (SELECT ROW_NUMBER() OVER ( PARTITION BY Category ORDER BY Price DESC ) AS 'RowNumber', RowID, Category, [ID], [Description], Price FROM @MyTable ) dt WHERE RowNumber <= 2 -- Results RowID Category ID Description Price 11 Bowl C1 Lg Mixing 27.50 12 Bowl C2 Sm Mixing 17.50 9 Pan B3 Bundt Cake 12.50 10 Pan B4 9x12 Brownie 7.95 6 Pot A6 Pressure Cooker 79.95 5 Pot A5 Stewpot 49.50 13 Tools T1 14" Spatula 9.95 Return to Top 

Solución SQL Server 2005 / SQL Server 2008 utilizando un CTE (Agregado por: Jacob Sebastian)

 -- Define a CTE with the name "dt" ;WITH dt AS ( SELECT ROW_NUMBER() OVER ( PARTITION BY Category ORDER BY Price DESC ) AS 'RowNumber', RowID, Category, [ID], [Description], Price FROM @MyTable ) -- and select the data from the CTE SELECT RowID, Category, [ID], [Description], Price FROM dt WHERE RowNumber <= 2 -- Results RowID Category ID Description Price 11 Bowl C1 Lg Mixing 27.50 12 Bowl C2 Sm Mixing 17.50 9 Pan B3 Bundt Cake 12.50 10 Pan B4 9x12 Brownie 7.95 6 Pot A6 Pressure Cooker 79.95 5 Pot A5 Stewpot 49.50 13 Tools T1 14" Spatula 9.95 Return to Top 

Solución SQL 2000

 --Query to Retrieve Desinetworking Data SELECT DISTINCT RowID, Category, [ID], [Description], Price FROM @MyTable t1 WHERE RowID IN (SELECT TOP 2 RowID FROM @MyTable t2 WHERE t2.Category = t1.Category ORDER BY Price DESC ) ORDER BY Category, Price DESC -- Results RowID Category ID Description Price 11 Bowl C1 Lg Mixing 27.50 12 Bowl C2 Sm Mixing 17.50 9 Pan B3 Bundt Cake 12.50 10 Pan B4 9x12 Brownie 7.95 6 Pot A6 Pressure Cooker 79.95 5 Pot A5 Stewpot 49.50 13 Tools T1 14" Spatula 9.95 

De: select las N filas superiores para cada grupo