2009-08-30 45 views
6

Tôi có bảng nàySQL Query, chọn 5 gần đây nhất trong mỗi nhóm

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 đề cập đến những gì ngôn ngữ kỷ lục là trong. Những gì tôi muốn làm là lấy một danh sách trong năm gần đây nhất (ORDER BY time_posted DESC LIMIT 5) ghi lại trong mỗi ngôn ngữ_id. Tôi có thể làm điều này trong một vòng lặp trong PHP với một số truy vấn SQL khác nhau nhưng tôi cảm thấy có một cách đơn giản hơn.

Tôi phải lấy một cuốn sách về SQL, haha.

Cảm ơn.

+1

cơ SQL gì? Thật không may là điều quan trọng - chuẩn SQL, PostgreSQL, MS SQL Server, Oracle, IBM DB2, v.v., có một cách tuyệt vời để làm chính xác những gì bạn muốn - nhưng nếu bạn bị mắc kẹt với MySQL, giải pháp hoàn hảo đó hoạt động tất cả các DB quan hệ tốt và theo tiêu chuẩn chính nó là không có sẵn, do đó, nó fudge-và-kludge thời gian (mệnh cho khóa học cho MySQL - thở dài). Vì vậy, nó sẽ là gì - mỗi thực hiện SQL phong nha trên hành tinh, trên một mặt, hoặc MySQL, mặt khác ...? –

+0

@Alex: Bỏ cuộc xung quanh bụi cây - hãy cho chúng tôi biết bạn cảm thấy thế nào về MySQL! Đừng giữ nó đóng chai. ;-) –

+0

mySQL> MS Access ...hầu như không –

Trả lời

9

Đây là cách tôi giải quyết việc này "top N cho mỗi nhóm" loại truy vấn trong 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; 

Xem thêm "How do I select multiple items from each group in a mysql query?"

+0

Xin lỗi vì đã bị trục trặc, nhưng C1 và C2 đã đến từ đâu? –

+0

chúng là bí danh bảng –

+0

Lưu ý rằng nếu 'time_posted' có thể có quan hệ bạn có thể nhận được một số kết quả thú vị. Hãy cho tôi biết nếu đây là một mối quan tâm bởi vì nó cũng có thể giải quyết được. –

-1

Đây là một giải pháp tuyệt vời Tôi chỉ được tìm thấy.

Chọn TOP n hàng cho mỗi Nhóm Arnie Rowland, 13 Tháng ba 2008

có nhiều hàng cho từng loại, và có một mong muốn chỉ chọn hai (2) Hàng TOP mỗi loại theo giá. Ví dụ, từ các dữ liệu sau:

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 

Kết quả mong muốn là:

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 

Có nhiều phương pháp để thực hiện các đầu ra mong muốn. cuộc biểu tình này cung cấp một giải pháp cho SQL Server 2005/SQL Server 2008, và sau đó một giải pháp cho SQL Server 2000.

Tạo dữ liệu mẫu cho Cả hai giải pháp

-- 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 

SQL Server 2005/SQL Server 2008 Giải pháp

--Query to Retrieve Desired 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 

SQL server 2005/SQL server 2008 giải pháp sử dụng một CTE (Added by: 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 

SQL 2000 Giải pháp

--Query to Retrieve Desired 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 

Từ: Select the TOP n Rows For Each Group

+0

Lưu ý rằng các câu trả lời chỉ có liên kết không được khuyến khích, các câu trả lời SO phải là điểm cuối của việc tìm kiếm giải pháp (so với một giải pháp khác) dừng lại của tài liệu tham khảo, mà có xu hướng để có được cũ theo thời gian). Vui lòng xem xét thêm bản tóm tắt độc lập tại đây, giữ liên kết dưới dạng tham chiếu. – kleopatra

Các vấn đề liên quan