Mysql通过另一列的顺序选择行组

时间:2013-05-30 12:49:00

标签: mysql sql

我试图通过'group by'从表中选择行,并忽略通过按日期排序数据得到的第一行。排序应该由日期字段完成,以忽略最新的条目并返回组的旧条目。

该表格如

+----+------------+-------------+-----------+
| id | updated on | group_name  | list_name |
+----+------------+----------------+--------+
| 1  | 2013-04-03 | g1          | l1        |
| 2  | 2013-03-21 | g2          | l1        |
| 3  | 2013-02-26 | g2          | l1        |
| 4  | 2013-02-21 | g1          | l1        |
| 5  | 2013-02-20 | g1          | l1        |
| 6  | 2013-01-09 | g2          | l2        |
| 7  | 2013-01-10 | g2          | l2        |
| 8  | 2012-12-11 | g1          | l1        |
+----+------------+-------------+-----------+

http://www.sqlfiddle.com/#!2/cec99/1

所以,基本上,我只想返回id(3,4,5,6,8),因为它们是group_name和list_name中最早的。忽略最新条目并通过基于group_name和list_name

对其进行分组来返回旧条目

我无法为这个问题编写sql。我知道订单不会与group by一起工作。请帮我弄清楚解决方案。

由于

而且,有没有办法在不使用子查询的情况下执行此操作?

3 个答案:

答案 0 :(得分:2)

类似以下内容,仅获取特定行的最小日期行:

select a.ID, a.updated_on, a.group_name, list_name
from data a 
where
a.updated_on < 
(
select max(updated_on)
from data 
group by group_name having group_name = a.group_name
);

SQL小提琴:http://www.sqlfiddle.com/#!2/00d43/10

更新(根据您的要求)

select a.ID, a.updated_on, a.group_name, list_name
from data a 
where
a.updated_on < 
(
select max(updated_on)
from data 
group by group_name, list_name having group_name = a.group_name
  and list_name = a.list_name
);

请参阅:http://www.sqlfiddle.com/#!2/cec99/3

更新(不使用相关子查询但使用简单子查询)

根据:Subqueries vs joins

确定相关子查询太慢

所以我改为使用基于嵌套查询的别名临时表加入。

select a.ID, a.updated_on, a.group_name, a.list_name
from data a,
(
select group_name, list_name , max(updated_on) as MAX_DATE
from data 
group by group_name, list_name 
) as MAXDATE   
where
a.list_name = MAXDATE.list_name AND
a.group_name = MAXDATE.group_name AND
a.updated_on < MAXDATE.MAX_DATE
;

SQL小提琴:http://www.sqlfiddle.com/#!2/5df64/8

答案 1 :(得分:0)

您可以尝试使用以下查询(是的,它有嵌套连接,但也许有帮助)。

SELECT ID FROM 
(select d1.ID FROM data d1 LEFT JOIN 
data d2 ON (d1.group_name = d2.group_name AND d1.list_name=d2.list_name AND 
d1.updated_on > d2.updated_on) WHERE d2.ID IS NULL) data_tmp;

<强> CORRECTION:

SELECT DISTINCT(ID) FROM 
(select d1.* FROM data d1 LEFT JOIN 
data d2 ON (d1.group_name = d2.group_name AND d1.list_name=d2.list_name AND 
d1.updated_on < d2.updated_on) WHERE d2.ID IS NOT NULL) date_tmp;

答案 2 :(得分:0)

SELECT DISTINCT y.id 
  FROM data x 
  JOIN data y 
    ON y.group_name = x.group_name 
   AND y.list_name = x.list_name 
   AND y.updated_on < x.updated_on;