2013-10-10 37 views
1

这里是我的SQL小提琴:http://sqlfiddle.com/#!2/90d45/3比较第一和最后一个SQL行用相同的ID

表方案:

CREATE TABLE domain_rankings (domain_id int, rank int, create_date datetime); 
INSERT INTO domain_rankings VALUES (1, 0, "2012-01-01"); 
INSERT INTO domain_rankings VALUES (1, 2, "2012-01-02"); 
INSERT INTO domain_rankings VALUES (1, 1, "2012-01-03"); 
INSERT INTO domain_rankings VALUES (2, 0, "2012-01-01"); 
INSERT INTO domain_rankings VALUES (2, 1, "2012-01-02"); 
INSERT INTO domain_rankings VALUES (2, 2, "2012-01-03"); 
INSERT INTO domain_rankings VALUES (3, 1, "2012-01-01"); 
INSERT INTO domain_rankings VALUES (4, 3, "2012-01-01"); 
INSERT INTO domain_rankings VALUES (4, 2, "2012-01-02"); 
INSERT INTO domain_rankings VALUES (4, 1, "2012-01-03"); 

我想要得到的域ID的是,在排名上的第一项比较的计数到最后一项(按日期)。

所以在这种情况下,所有等级上升的计数应该是2(domain_id:1,2)。

domain_id 3不应包含在计数中,因为它只有一个条目。所以,可能需要一个子查询HAVING COUNT(*)> 1.

domain_id 4也不应该包括在计数中,除非我反转查询并希望排名下降。

我应该如何解决这个问题?我知道我需要子查询,但我不知道从哪里开始。 JSFiddle应该让你知道我卡在哪里。

尝试 - 它返回有效的行,而不是行数正确:

SELECT domain_id, COUNT(DR.domain_id) 
FROM domain_rankings DR 
WHERE 
    (SELECT rank 
    FROM domain_rankings 
    WHERE domain_rankings.domain_id = DR.domain_id 
    ORDER BY create_date ASC LIMIT 1 
) > (
    SELECT rank 
    FROM domain_rankings 
    WHERE domain_rankings.domain_id = DR.domain_id 
    ORDER BY create_date DESC LIMIT 1 
) 
GROUP BY DR.domain_id 
HAVING count(*) > 1 

最终答案(两个选项更慢):

SELECT COUNT(a.domain_id) cnt 
FROM (
    SELECT domain_id,MIN(create_date) mind, MAX(create_date) maxd 
    FROM domain_rankings 
    GROUP BY domain_id 
    HAVING COUNT(*) > 1 
) master 
JOIN domain_rankings a 
    ON a.domain_id = master.domain_id 
AND a.create_date = master.mind 
JOIN domain_rankings b 
    ON b.domain_id = master.domain_id 
AND b.create_date = master.maxd 
WHERE a.rank < b.rank 
+0

你能发布你的预期表结果吗? –

+0

我以为我做到了? 结果应该是: 如果我希望所有关键字的排名都上升,结果应该是2. 如果我希望所有关键字排名下降,结果应该是1. 我们忽略domain_id 3,因为它只有一行。 –

回答

1

也许不是最简单的方法,但是您可以使用子查询来获取每个domain_id的最小和最大日期,并使用常规联接来获取相应的行。然后你可以在最后比较排名;

SELECT COUNT(a.domain_id) cnt 
FROM (SELECT domain_id,MIN(create_date) mind, MAX(create_date) maxd 
     FROM domain_rankings GROUP BY domain_id) master 
JOIN domain_rankings a 
    ON a.domain_id = master.domain_id AND a.create_date = master.mind 
JOIN domain_rankings b 
    ON b.domain_id = master.domain_id AND b.create_date = master.maxd 
WHERE a.rank < b.rank 

另一个版本是只使用左连接过滤掉第一行和最后一行,并比较排名;

SELECT COUNT(a.domain_id) cnt 
FROM domain_rankings a JOIN domain_rankings b 
    ON a.domain_id = b.domain_id AND a.rank < b.rank 
LEFT JOIN domain_rankings c 
    ON a.domain_id = c.domain_id AND a.create_date > c.create_date 
LEFT JOIN domain_rankings d 
    ON b.domain_id = d.domain_id AND b.create_date < d.create_date 
WHERE c.domain_id IS NULL and d.domain_id IS NULL; 

An SQLfiddle with both

+0

我修改了第一个,在master上也有一个HAVING COUNT(*)> 1。非常感谢你! –

0
SELECT count(*) 
FROM TABLE AS a 
INNER JOIN TABLE AS b ON a.domain_id=b.domain_id 
AND a.date=b.date-interval 2 DAY 
AND a.rank<b.rank 
+0

考虑扩大你的答案,向提问者解释为什么达到了预期的结果,可能会链接到文档。如此,这仅仅是有用的。 –

+0

对不起,但这对于表格来说太具体了 - 如果我的日期发生变化,不幸的是,这个时间段不适用于间隔。 –

相关问题