2009-08-30 5 views
6

각 그룹에서 가장 최근의 5를 선택SQL 쿼리, 나는이 표를 가지고

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 레코드가. 에 어떤 언어 내가하고 싶은 것은 무엇을 의미하는 것은 가장 최근의 5의 목록을 검색하다 (ORDER BY time_posted DESC LIMIT 5)는 각 언어 ID에 을 기록합니다. 여러 SQL 쿼리를 사용하여 PHP 내에서 루프를 수행 할 수 있지만 더 간단한 방법이 있다고 느낍니다.

나는 SQL에 관한 책을 얻었습니다. 하하.

감사합니다. 여기

+1

무엇 SQL 엔진? 불행히도 중요한 것은 SQL 표준, PostgreSQL, MS SQL Server, Oracle, IBM DB2 등은 원하는대로 정확하게 수행 할 수있는 훌륭한 방법 중 하나입니다. 그러나 MySQL에 익숙하다면 모든 좋은 관계형 DB와 표준 자체에 따르면, 그래서 그것은 퍼지 -와 - kludge 시간 (MySQL을위한 코스 - 한숨)입니다. 그렇다면 행성, 한 쪽 또는 다른쪽에있는 MySQL의 모든 알맞은 SQL 구현은 무엇일까요? –

+0

@Alex : 부시 주위에서 치다 - 당신이 MySQL에 대해 어떻게 느끼는지 알려주세요! 병에 넣어 두지 마십시오. ;-) –

+0

mySQL> MS 액세스 ...간신히 –

답변

9

내가 MySQL의 쿼리의 "상위 N 그룹 당"유형을 해결하는 방법은 다음과 같습니다

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; 

도 참조 "How do I select multiple items from each group in a mysql query?"

+0

미안하지만, C1과 C2는 어디에서 왔습니까? –

+0

그들은 테이블 별칭입니다. –

+0

'time_posted '에 동점이있을 수 있다면 흥미로운 결과가 나올 수 있습니다. 이것이 해결 될 수 있기 때문에 이것이 우려 사항인지 알려주십시오. –

-1

여기 난 그냥 볼 수있는 좋은 솔루션입니다.

를 들어 TOP N 행을 선택하고 각 그룹 애니 로우 랜드 2008 년 3 월 13 일

각 범주에 대한 여러 행이 있으며, 카테고리 당 최고 2 개의 행을 선택하는 욕망이있다 가격. 다음 데이터에서 예를 들면 :

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 

원하는 출력은 : 원하는 출력을 달성하기 위해 여러 가지 방법이있다

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 

. 이 데모는 SQL 서버 2005/SQL 서버 2008, 다음 SQL Server의 솔루션은 2000

두 솔루션

에 대한 샘플 데이터를 생성
-- 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 서버 2005/SQL 서버 2008 솔루션에 대한 솔루션을 제공합니다

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

CTE를 를 사용하여 2008 솔루션 (작성자 : 야곱 세바스찬) SQL 서버 2005/SQL 서버

01 SQL 2000 23,516,
-- 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 

에서 해결

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

: Select the TOP n Rows For Each Group

+0

링크 전용 답변은 권장되지 않으므로 SO 답변은 솔루션 검색의 종점이어야합니다 (대 시간이 경과함에 따라 부실 해지는 경향이있는 참조의 중간 기착). 링크를 참조 용으로 유지하면서 독립형 시놉시스를 여기에 추가하는 것을 고려해보십시오. – kleopatra