2012-08-08 63 views
2

我已經(簡化)以下模型的每個項目的最高排名:查詢來獲取

Book 
    id 
    name 

BookCategory 
    book_id 
    category_id 
    rank 

Category 
    id 
    name 

對於給定的類ID,我想獲得具有類書籍中排名最高一。

我舉個例子是關於它的更加清晰:

Book 

id name 
--- ------- 
1  On Writing 
2  Zen teachings 
3  Siddharta 

BookCategory 

book_id category_id  rank 
---  -------  ----- 
1  2    34.32 
1  5    24.23 
1  9    54.65 
2  5    27.33 
2  9    28.32 
3  2    30.43 
3  5    27.87 

Category 

id name 
--- ------- 
2  Writing 
5  Spiritual 
9  Buddism 

爲CATEGORY_ID結果= 2將是書ID = 3

這是我的查詢運行:

SELECT book."name" AS bookname 
FROM bookcategory AS bookcat 
LEFT JOIN book ON bookcat."book_id" = book."id" 
LEFT JOIN category cat ON bookcat."category_id" = cat."id" 
WHERE cat."id" = 2 
ORDER BY bookcat."rank" 

這不是正確的做法,因爲它沒有選擇每本書的最高排名。我還沒有找到合適的解決方案。

注意:我正在使用postgresql 9.1版本。

編輯:

DB模式(從馬丁的SQL小提琴回答):

create table Book (
    id int, 
    name varchar(16) 
); 

insert into Book values(1, 'On Writing'); 
insert into Book values(2, 'Zen teachings'); 
insert into Book values(3, 'Siddharta'); 

create table BookCategory (
    book_id int, 
    category_id int, 
    rank real 
); 

insert into BookCategory values(1,2,34.32); 
insert into BookCategory values(1,5,24.23); 
insert into BookCategory values(1,9,54.65); 
insert into BookCategory values(2,5,27.33); 
insert into BookCategory values(2,9,28.32); 
insert into BookCategory values(3,2,30.43); 
insert into BookCategory values(3,5,27.87); 

create table Category (
    id int, 
    name varchar(16) 
); 

insert into Category values(2, 'Writing'); 
insert into Category values(5,'Spiritual'); 
insert into Category values(9, 'Buddism'); 
+0

如果你能證明你的例子爲表結構及數據'CREATE TABLE'和'INSERT'聲明,人們可以複製並粘貼到一個測試數據庫來嘗試解決方案之前,張貼。 – kgrittn 2012-08-08 17:14:00

回答

1

要設置:

CREATE TABLE Book 
(
    id int PRIMARY KEY, 
    name text not null 
); 

CREATE TABLE Category 
(
    id int PRIMARY KEY, 
    name text not null 
); 

CREATE TABLE BookCategory 
(
    book_id int, 
    category_id int, 
    rank numeric not null, 
    primary key (book_id, category_id) 
); 

INSERT INTO Book VALUES 
    (1, 'On Writing'), 
    (2, 'Zen teachings'), 
    (3, 'Siddharta'); 

INSERT INTO Category VALUES 
    (2, 'Writing'), 
    (5, 'Spiritual'), 
    (9, 'Buddism'); 

INSERT INTO BookCategory VALUES 
    (1, 2, 34.32), 
    (1, 5, 24.23), 
    (1, 9, 54.65), 
    (2, 5, 27.33), 
    (2, 9, 28.32), 
    (3, 2, 30.43), 
    (3, 5, 27.87); 

解決辦法:

SELECT Book.name 
    FROM (
     SELECT DISTINCT ON (book_id) 
      * 
      FROM BookCategory 
      ORDER BY book_id, rank DESC 
     ) t 
    JOIN Book ON Book.id = t.book_id 
    WHERE t.category_id = 2 
    ORDER BY t.rank; 

從邏輯上講,FROM子句中的子查詢生成最高排序的類別爲每本書,從中再選擇的關係該類別中的書籍,並按該類別中的排名排列。

結果:

 
    name  
----------- 
Siddharta 
(1 row) 
4

另一列添加計算排名:

dense_rank() OVER (PARTITION BY book."name" ORDER BY bookcat."rank" 
s ASC) AS rank 
1

這是你想要的嗎?

SELECT 
    book.name, mx.max_rank 
FROM 
    (SELECT 
    max(rank) AS max_rank , book_id 
    FROM BookCategory WHERE category_id = 2 
    GROUP BY 
    book_id 
) mx 
JOIN Book ON 
    mx.book_id = Book.id 

如果我正確理解你的問題,你需要得到最大給定類別,每本書BookCategory(即內選擇做什麼),然後簡單地將其加入到書籍表上book_id。

整個例子是SQL Fiddle

編輯:

我看到已經有一個公認的答案,但爲了完整起見,這裏是我的回答澄清的問題如下:

SELECT 
    Book.name 
FROM 
    (SELECT max(rank) AS max_rank, book_id AS bid 
    FROM BookCategory GROUP BY book_id 
) mx 
JOIN BookCategory ON 
    rank = max_rank 
    AND book_id = bid 
JOIN Book 
    ON book_id = Book.id 
WHERE category_id = 2 

On SQL Fiddle

+0

謝謝你的答案馬丁,但結果是不正確的。查詢返回id爲1和3的書籍,但正確的回覆僅爲id = 3(siddartha)的書籍。 id = 1的書的最高排名是id = 9的排名。 – Rod0n 2012-08-08 16:40:00