使用子查询中的min()结果返回多个记录

时间:2017-08-17 16:40:52

标签: sql group-by amazon-redshift

希望这个问题的答案很简单(似乎它应该是,但我遗漏了一些东西)....我有一个简单的查询,从表中获取最小值(通过子查询),然后使用该最小值尝试获得最终结果之间的简单月份

我试图尽可能简单地回答的问题是:最早的end_date是什么,以及report_date距离此end_date的距离

这是查询

select end_date term_date, months_between (cast (report_date as date), cast (end_date as date)) term_length
from table1
where end_date = 
  (select min (end_date) end_date
    from table1
    where rec_load_date = (select max (rec_load_date) from table1)
      and active_rec = 'Y' and end_date <= report_date);

我的问题是,虽然子查询工作正常,即我得到一个min(end_date)值,在主查询中使用它返回多个记录。 (见图片)

目前的结果: 1. term_date = min(table1.end_date) 2. term_length = months_ between value compare table1.report_date和table1.end_date(即table1中记录的实际end_date值)

当前结果(附图):

返回的记录样本(与table1中适用的end_date值一样多的行)

示例数据:

create table table1 (rec_load_date varchar(25), report_date as varchar (25), end_date as varchar (25));
insert into table1 (rec_load_date, report_date, end_date) values ('2017-08-10', '2017-07-31', '2017-02-28');
insert into table1 (rec_load_date, report_date, end_date) values ('2017-08-10', '2017-07-31', '2017-01-31');
insert into table1 (rec_load_date, report_date, end_date) values ('2017-08-10', '2017-07-31', '2017-04-30');
insert into table1 (rec_load_date, report_date, end_date) values ('2017-08-10', '2017-07-31', '2017-03-31');
insert into table1 (rec_load_date, report_date, end_date) values ('2017-08-10', '2017-07-31', '2017-01-31');
insert into table1 (rec_load_date, report_date, end_date) values ('2017-08-10', '2017-07-31', '2017-04-25');
insert into table1 (rec_load_date, report_date, end_date) values ('2017-08-10', '2017-07-31', '2017-01-31');

关于我如何从查询中获得以下结果的任何想法:'2017-01-31',6

Multiple recs returned

2 个答案:

答案 0 :(得分:0)

您的示例数据看起来不完整,但我暂时忽略了丢失的rec_load_date,并假设您的SELECT MIN(end_date)将正确返回一个值:2017-01-31

然后外部查询有效地搜索select all rows from table1 where end_date = '2017-01-31'并且有3行(在您的示例数据中,可能在您的真实表格中更多)符合此条件。所以你得到了多行!

如果你只想获得一排,那么你将不得不更加专注。使用ROW_NUMBER() OVER(...ORDER BY x)对行进行编号,然后选择rownumber为1的行是单向的,即使存在重复。不过要注意;你没有一种简单的方法来保证WHICH行被编号为1,如果你在end_date上做了一个天真的排序,其中存在多个相同的值。要么增加您订购的列数,要么选择不同的排序键。

答案 1 :(得分:0)

根据您的评论,您可以使用:

select
    report_date
    ,datediff(day,report_date,min(end_date)) as DaysBack
from
    table1
group by 
   report_date

这仍然可以为您提供每一行的回溯。如果您想要最早或最新report_date,那么您可以按TOP 1

添加订单
select top 1
    report_date
    ,datediff(day,report_date,min(end_date)) as DaysBack
from
    table1
group by 
    report_date
order by
    report_date asc --or desc