MySQL查询每月选择一组项目

时间:2012-11-20 12:05:31

标签: mysql sql datetime select

例如我有下表:

items
-----
item_id    (usigned-int, not-null, auto-increment, primary)
created_at (datetime, not-null)
...

我有以下数据集:

(1, 01/01/2012)
(2, 03/01/2012)
(3, 07/01/2012)
(4, 12/01/2012)
(5, 28/01/2012)
(6, 02/02/2012)
(7, 06/02/2012)
(8, 13/02/2012)
(9, 27/02/2012)

我想得到以下结果:

(3, 07/01/2012)
(4, 12/01/2012)
(5, 28/01/2012)
(8, 13/02/2012)
(9, 27/02/2012)

即。每个月的每个第一(n = 2)条记录都会被跳过。

我如何通过MySQL实现这一目标?

3 个答案:

答案 0 :(得分:1)

根据分区内项目的排名进行选择:

create table items (
    item_id    int,
    created_at datetime
);


insert into items
select 1, '2012-01-01' union
select 2, '2012-01-03' union
select 3, '2012-01-07' union
select 4, '2012-01-12' union
select 5, '2012-01-28' union
select 6, '2012-02-02' union
select 7, '2012-02-06' union
select 8, '2012-02-13' union
select 9, '2012-02-28'


select i.*
from items i
join (
  select t.item_id, count(item_id1) as row_no
  from (
    select t.item_id, t1.item_id as item_id1
    from items t
    join items t1 on t.item_id >= t1.item_id and 
      DATE_FORMAT(t.created_at, '%Y%m') = DATE_FORMAT(t1.created_at, '%Y%m')
  ) t
  group by t.item_id
) g on i.item_id = g.item_id
where g.row_no > 2

Live example on SQL Fiddle

答案 1 :(得分:1)

尝试此查询 -

SELECT id, created_at FROM (
  SELECT t1.*, COUNT(*) r FROM items t1
    LEFT JOIN items t2
      ON MONTH(t2.created_at) = MONTH(t1.created_at) AND t2.id <= t1.id
  GROUP BY
    MONTH(t1.created_at), t1.id
  ) t
WHERE r > 2;

您还需要按年度过滤,或者只需添加条件 -

SELECT id, created_at FROM (
  SELECT t1.*, COUNT(*) r FROM items t1
    LEFT JOIN items t2
      ON YEAR(t2.created_at) = YEAR(t1.created_at) AND
         MONTH(t2.created_at) = MONTH(t1.created_at) AND
         t2.id <= t1.id
  GROUP BY
    YEAR(t1.created_at), MONTH(t1.created_at), t1.id
  ) t
WHERE r > 2;

答案 2 :(得分:0)

SELECT item_id, created_at, 
    CASE WHEN @month IN (RIGHT(created_at, 7), 0) 
        THEN @rownum := @rownum + 1 
        ELSE @rownum := 1 END AS rownum,
    @month = RIGHT(created_at, 7) AS dummy
FROM (  SELECT item_id, created_at
        FROM items
        ORDER BY created_at DESC) AS h,
    (   SELECT @rownum := 0, @month := 0) AS vars
HAVING rownum > 2