2012-11-08 78 views
3

我想選擇查詢中行的最後1/x部分,以某種方式排序。我怎樣才能做到這一點?如何從查詢中選擇最後的x%行?

我拿出像

SELECT avg(smilies_count) 
FROM posts AS p 
WHERE time >= (???) -- I only want the last 25% of posts in this thread 
GROUP BY thread_id; -- each thread can have more than 1 post, but I still only 
        -- want to consider the last 25% of posts in my average 

,但我不是太肯定要放什麼東西在???,不會導致極其粗糙的表達。

編輯

我試圖把

SELECT min(p2.time) 
FROM posts AS p2 
WHERE p2.thread_id = p.thread_id 
ORDER BY p2.time DESC 
LIMIT count(*)/4 

???,但只給了我

Error: misuse of aggregate function count() 
+0

你在posts表中有一個post_id列嗎?和解決方案應該只有sqlite? – pkmiec

+0

@Dooh是的,我確實有一個post_id,任何解決方案都應該沒問題,只要它在SQLite中也可以。 – wrongusername

回答

2

我假設你基本上要由每個線程最後職位的25%,以後的操作是由您決定。

如果我是正確的,那麼這段代碼應該爲你工作(爲MS-SQL編寫的,應該可以移植到易源碼):

CREATE TABLE posts (
    post_id INT, 
    thread_id INT 
) 

INSERT INTO posts(post_id, thread_id) VALUES (1, 1) 
INSERT INTO posts(post_id, thread_id) VALUES (2, 2) 
INSERT INTO posts(post_id, thread_id) VALUES (3, 2) 
INSERT INTO posts(post_id, thread_id) VALUES (4, 3) 
INSERT INTO posts(post_id, thread_id) VALUES (5, 3) 
INSERT INTO posts(post_id, thread_id) VALUES (6, 3) 
INSERT INTO posts(post_id, thread_id) VALUES (7, 3) 
INSERT INTO posts(post_id, thread_id) VALUES (8, 3) 
INSERT INTO posts(post_id, thread_id) VALUES (9, 3) 
INSERT INTO posts(post_id, thread_id) VALUES (10, 3) 
INSERT INTO posts(post_id, thread_id) VALUES (11, 3) 

SELECT src.* 
FROM (
    SELECT post_number = (
     SELECT 1 + COUNT(*) 
     FROM posts pp 
     WHERE p.post_id > pp.post_id 
     AND p.thread_id = pp.thread_id 
    ), 
    post_id, 
    thread_id 
    FROM posts p 
) src 
JOIN (
    SELECT thread_id, cnt = COUNT(*) 
    FROM posts 
    GROUP BY thread_id 
) counts 
ON src.thread_id = counts.thread_id 
WHERE (CONVERT(FLOAT, src.post_number)/CONVERT(FLOAT, counts.cnt)) >= 0.75 

請注意,這不是高性能的查詢,主要是由於子查詢獲取post_number。對於支持它的DBMS,它可以用OVER子句寫得更好。

+0

非常感謝,終於搞定了。我想SQL可能不是最適合這項任務的語言,哈哈 – wrongusername

-1

這是在的情況下一個版本,你需要最後25整篇文章的百分比:

select 
    avg(1.0 * smilies_count) avg_count, 
from (select top 25% * from posts order by time desc) last_posts 

這是上崗的每個線程的最後25%多了一個:

select 
    avg(1.0 * smilies_count) avg_smilies 
from (
    select 
    thread_id, post_id, smilies_count, 
    row_number() over (partition by thread_id order_by time desc) row_num 
    from posts 
) p 
join (select thread_id, count(*) cnt from posts group by thread_id) c on 
    p.thread_id = c.thread_id 
where 
    p.row_num < 0.25 * c.cnt 
group by 
    p.thread_id 
+2

我想你已經錯過了要求每個線程都獲得最後25%的帖子,這在問題中隱含地陳述了(樣本查詢中的「按線程ID分組」) – pkmiec

+0

@Dooh不確定它是否隱含地從「group by」條款但確定:) – pkuderov

+0

@pkuderov你能解釋一下'last_post'的用途嗎? –