如何为每组具有共同价值的行选择第一行

时间:2019-03-05 19:53:41

标签: sql sql-server

例如,我有一个像这样的表:

week_dt     cust    y_w     w   y       y_fp
2011-01-29  ABC     201122  6   2011    201106
2011-02-05  ABC     201123  6   2011    201106
2011-02-12  ABC     201124  6   2011    201106
2011-02-19  ABC     201125  7   2011    201107
2011-02-26  ABC     201126  7   2011    201107
2011-03-05  ABC     201127  7   2011    201107
2011-03-12  ABC     201128  7   2011    201107
2011-03-19  ABC     201129  8   2011    201108
2011-03-26  ABC     201130  8   2011    201108
2011-04-02  ABC     201131  8   2011    201108
2011-04-09  ABC     201132  8   2011    201108
2011-04-16  ABC     201133  9   2011    201109
2011-04-23  ABC     201134  9   2011    201109

最后一列包含年份/财政年度信息。我想为每个y_fp元素选择一行,其中week_dty_w是该年/财年的第一个日期。因此,从上面进行选择将产生:

week_dt     cust    y_w     w   y       y_fp
2011-01-29  ABC     201122  6   2011    201106
2011-02-19  ABC     201125  7   2011    201107
2011-03-19  ABC     201129  8   2011    201108
2011-04-16  ABC     201133  9   2011    201109

我尝试使用TOP(1)而不是LIMIT跟随this example,但是我得到了整个桌子。

这是我的查询:

SELECT * FROM ( 
    SELECT
    md.week_dt, 
    md.cust, 
    md.y_w, 
    md.y, 
    md.w, 
    md.y_fp, 
    FROM MASTER_DATES md
) t1
Where 
    t1.week_dt IN (
    SELECT TOP(1) t2.week_dt
    FROM MASTER_DATES t2
    WHERE t2.week_dt = t1.week_dt AND t2.cust = t1.cust
    ORDER BY t2.week_dt
)
ORDER BY t1.week_dt

请注意,MASTER_DATES包含列week_dtcust中的复合主键。

3 个答案:

答案 0 :(得分:1)

尝试使用row_number和一个分区,将其除以md.y_fp

int integerinput = Integer.parseInt(input);
float floatInput = Float.parseFloat(input);

答案 1 :(得分:1)

一种方法是module DelayedTasks class A include DelayedEmails end class B end class C end class D end end

row_number()

但是,在某些情况下,相关子查询具有更好的性能:

select md.*
from (select md.*,
             row_number() over (partition by md.cust, md.y_fp order by md.week_date desc) as seqnum
      from master_dates md
     ) md
where seqnum = 1;

为了获得最佳性能,您需要在select md.* from master_dates md where md.week_date = (select min(md2.week_date) from master_dates md2 where md2.cust = md.cust and md2.y_fp = md.y_fp ); 上建立索引。

尽管答案中没有明确说明,但这些答案都假定您需要每个客户的信息。

答案 2 :(得分:1)

您的样本数据和预期结果表明,简单的分组依据就足够了:

select
  min(week_dt) week_dt, 
  cust,
  min(y_w) y_w,
  w,
  y,
  y_fp
from MASTER_DATES 
group by cust, y, w, y_fp