首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从组中选择最老的两条记录

从组中选择最老的两条记录
EN

Stack Overflow用户
提问于 2013-09-13 21:29:37
回答 4查看 858关注 0票数 3

我已经找到了一些示例,展示了如何从分组集合中选择单个最老的/最新的行,但是在从数据集中获取最老的两行时遇到了困难。

这是我的样品表:

代码语言:javascript
复制
CREATE TABLE IF NOT EXISTS `orderTable` (
  `customer_id` varchar(10) NOT NULL,
  `order_id` varchar(4) NOT NULL,
  `date_added` date NOT NULL,
  PRIMARY KEY (`customer_id`,`order_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO `orderTable` (`customer_id`, `order_id`, `date_added`) VALUES
('1234', '5A', '1997-01-22'),
('1234', '88B', '1992-05-09'),
('0487', 'F9', '2002-01-23'),
('5799', 'A12F', '2007-01-23'),
('1234', '3A', '2009-01-22'),
('3333', '7FHS', '2009-01-22'),
('0487', 'Z33', '2004-06-23'),
('3333', 'FF44', '2013-09-11'),
('3333', '44f5', '2013-09-02');

此查询返回两行以上:

代码语言:javascript
复制
SELECT customer_id, order_id, date_added
FROM orderTable T1
WHERE (
   select count(*) FROM orderTable T2
   where T2.order_id = T1.order_id AND T2.date_added <= T1.date_added
) <= 2;

因为我不是在寻找一行,所以这不是一个标准的greatest-n-per-group类型查询。

我错过了什么,我可以得到前两个订单为每个customer_id?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-09-13 21:46:21

最好(也就是最有表现力的)方法是在查询中使用用户定义的变量。

代码语言:javascript
复制
SELECT tmp.customer_id, tmp.date_added 
FROM ( 
  SELECT 
    customer_id, date_added, 
    IF (@prev <> customer_id, @rownum := 1, @rownum := @rownum+1 ) rank,
    @prev := customer_id
  FROM orderTable t 
  JOIN (SELECT @rownum := NULL, @prev := 0) r 
  ORDER BY t.customer_id
) tmp 
WHERE tmp.rank <= 2 
ORDER BY customer_id, date_added

结果

代码语言:javascript
复制
| CUSTOMER_ID |                       DATE_ADDED |
|-------------|----------------------------------|
|        0487 |   January, 23 2002 00:00:00+0000 |
|        0487 |      June, 23 2004 00:00:00+0000 |
|        1234 |       May, 09 1992 00:00:00+0000 |
|        1234 |   January, 22 1997 00:00:00+0000 |
|        3333 |   January, 22 2009 00:00:00+0000 |
|        3333 | September, 02 2013 00:00:00+0000 |
|        5799 |   January, 23 2007 00:00:00+0000 |

小提琴这里.

注意,join只是用来初始化变量。

票数 3
EN

Stack Overflow用户

发布于 2013-09-13 21:48:45

您的原始查询应该是(在子查询中使用customer_id )

代码语言:javascript
复制
SELECT customer_id, order_id, date_added
FROM orderTable T1
WHERE (
   select count(*) FROM orderTable T2
   where T2.customer_id = T1.customer_id AND T2.date_added <= T1.date_added
) <= 2;

还可以使用变量:

代码语言:javascript
复制
SELECT customer_id, order_id, date_added FROM (
SELECT customer_id, order_id, date_added,
@rownum := if(@prev_cust = customer_id, @rownum + 1,1) as rn,
@prev_cust := customer_id cust_var
FROM orderTable T1,
  (SELECT @rownum := 0) r,
  (SELECT @prev_cust := '') c
order by customer_id, date_added 
) o where o.rn < 3;

SQL演示

票数 3
EN

Stack Overflow用户

发布于 2013-09-13 21:51:34

下面是另一种(故意不完整的)方法,尽管其他方法可能对性能有一定的意义.

代码语言:javascript
复制
SELECT x.*
     , COUNT(*) rank 
  FROM ordertable x 
  JOIN ordertable y 
    ON y.customer_id = x.customer_id 
   AND y.date_added <= x.date_added 
 GROUP 
    BY x.customer_id 
     , x.date_added;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18795551

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档