比较具有相同id的第一个和最后一个SQL行

时间:2013-10-10 19:24:48

标签: mysql

这是我的SQL小提琴:http://sqlfiddle.com/#!2/90d45/3

表格方案:

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");

我希望得到的domain_id的数量在排名上比较第一个条目和最后一个条目(按日期)。

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

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

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

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

尝试 - 这会返回有效的行,但不会正确返回行的COUNT:

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

2 个答案:

答案 0 :(得分: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

另一个版本是使用LEFT JOINS过滤掉第一行和最后一行,并比较排名;

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

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