2015-09-06 107 views
0

首先,请原谅语言,我一直无法将我的问题解析为真实的英语,所以如果有人可以编辑以使其更清楚,那将有所帮助。获得每组最后[n,n + t]天

我一直在努力争取一段时间。我需要每个组从过去N天开始的查询,跳过最近的一个并检索下一个T天。这是经典的'LIMIT with GROUP'问题的一个版本,事实上,我尝试过的其中一个查询无效,使用了这种形式。

MRE如下:

CREATE TABLE `trying` (id INTEGER PRIMARY KEY AUTO_INCREMENT, types1 TEXT, stuffs INTEGER, dates DATE); 
INSERT INTO `trying`(types1, stuffs, dates) VALUES("one",123,'2015-09-06'); 
INSERT INTO `trying`(types1, stuffs, dates) VALUES("one",67,'2015-09-05'); 
INSERT INTO `trying`(types1, stuffs, dates) VALUES("one",45,'2015-09-04'); 
INSERT INTO `trying`(types1, stuffs, dates) VALUES("one",98,'2015-09-03'); 
INSERT INTO `trying`(types1, stuffs, dates) VALUES("one",89,'2015-09-02'); 
INSERT INTO `trying`(types1, stuffs, dates) VALUES("two",56,'2015-09-02'); 
INSERT INTO `trying`(types1, stuffs, dates) VALUES("two",34,'2015-09-01'); 
INSERT INTO `trying`(types1, stuffs, dates) VALUES("two",98,'2015-08-31'); 
INSERT INTO `trying`(types1, stuffs, dates) VALUES("two",34,'2015-08-30'); 
INSERT INTO `trying`(types1, stuffs, dates) VALUES("two",12,'2015-08-29'); 
INSERT INTO `trying`(types1, stuffs, dates) VALUES("three",3,'2015-09-06'); 
INSERT INTO `trying`(types1, stuffs, dates) VALUES("three",8,'2015-09-04'); 
INSERT INTO `trying`(types1, stuffs, dates) VALUES("three",80,'2015-09-02'); 
INSERT INTO `trying`(types1, stuffs, dates) VALUES("three",9,'2015-09-01'); 
INSERT INTO `trying`(types1, stuffs, dates) VALUES("three",6,'2015-08-31'); 

在表trying有三种types1 '类型': '一个', '2' 和 '3',和有每组5周的观察。请注意,各组之间的日期不相似,甚至可能存在差距(so no dates BETWEEN, like in this question)。

在这个例子中,我想要得到一个表,每个组有三个中间值。所以跳过第一个和最后一个值,预期的输出应该是这样的:

types1 stuffs dates 
one  67  2015-09-05 
one  45  2015-09-04 
one  98  2015-09-03 
two  34  2015-09-01 
two  98  2015-08-31 
two  34  2015-08-30 
three 8  2015-09-04 
three 80  2015-09-02 
three 9  2015-09-01 

一对夫妇的查询,没有工作:

可能工作
SELECT types1, stuffs, dates FROM trying GROUP BY types1 LIMIT 2,4; 
/*this returned the following */ 
types1 stuffs dates 
two  56  2015-09-02 


SELECT trying.* FROM (SELECT types1, stuffs, dates FROM trying) GROUP BY trying.types1 OFFSET 2,4; 
/*threw out an error: Every derived table must have its own alias */ 
+0

我讨论米的解决方案y groupwise max博客:(mysql.rjweb.org/doc.php/groupwise_max)。 –

回答

1
select types1,stuffs,dates from (
select @rank:=if(@prev_cat=types1,@rank+1,1) as rank, 
    types1,stuffs,dates,@prev_cat:=types1 

from trying,(select @rank:=0, @prev_cat:="")t 
order by types1, dates desc 
) temp 

    where rank between 2 and 4 
2

一种方法是使用用户变量各组在数量的行,然后限制结果在所需的间隔与行号的行:

SELECT id, types1, stuffs, dates 
FROM (
    SELECT 
    id, types1, stuffs, dates, 
    (
     CASE types1 
     WHEN @type 
     THEN @row := @row + 1 
     ELSE @row := 1 AND @type := types1 END 
    ) + 1 AS row 
    FROM trying p, 
    (SELECT @row := 0, @type := '') r 
    ORDER BY types1, dates asc 
) src 
WHERE row BETWEEN 2 AND 4 
ORDER BY id; 

Sample SQL Fiddle查询1

或者,如果你总是希望删除的每个组中的第一个和最后一个行,那么你可以使用一个左连接到一个派生表,返回各组的最大值和最小值日期:

select t.* from trying t 
left join (
    select types1, min(dates) min_dates, max(dates) max_dates 
    from trying group by types1 
    ) minmax 
    on t.types1 = minmax.types1 
    and t.dates in (minmax.max_dates, minmax.min_dates) 
where minmax.types1 is null; 

Sample SQL Fiddle为查询2

与样品数据这两个查询返回相同的结果:

| id | types1 | stuffs |      dates | 
|----|--------|--------|-----------------------------| 
| 2 | one |  67 | September, 05 2015 00:00:00 | 
| 3 | one |  45 | September, 04 2015 00:00:00 | 
| 4 | one |  98 | September, 03 2015 00:00:00 | 
| 7 | two |  34 | September, 01 2015 00:00:00 | 
| 8 | two |  98 | August, 31 2015 00:00:00 | 
| 9 | two |  34 | August, 30 2015 00:00:00 | 
| 12 | three |  8 | September, 04 2015 00:00:00 | 
| 13 | three |  80 | September, 02 2015 00:00:00 | 
| 14 | three |  9 | September, 01 2015 00:00:00 |