2

我对 SQL 不是很熟悉,我希望这里的一些专家可以向我展示我想要实现的合适且高效的查询。顺便说一句,我正在使用 DB2。

下面是示例数据的屏幕截图。我需要的是对于给定的年份,选择具有不同 ID1+ID2+Name 列和最大(最近)有效日期(以 YYYYMMDD 格式,存储为整数)的记录,上述年份介于 YearFrom 和 YearTo 范围之间。

在此处输入图像描述

对于看不到屏幕截图的任何人:

NAME     YearFrom     YearTo    ID1    ID2    EffDate
item1    2002         2005      AB     10     20091201
item1    2009         2013      AB     10     20100301
item2    2001         2004      XX     20     20050103 
item2    2002         2009      XX     20     20060710 
item2    2007         2013      XX     20     20090912 
item3    2005         2010      YY     30     20110304 

我希望我解释得很好。例如,如果用户正在寻找 2011 年的可用项目,则会返回项目 1(有效期为 20100301)和项目 2(有效期为 20090912)。

如果有人正在寻找 2008 年可用的项目:项目 2(生效日期为 20090912)和项目 3 将被退回。在这种情况下,项目 1 将不会被退回,因为项目 1 的最新记录的范围是 2009-2013。

我有查询的第一部分是正确的,但我不知道如何根据一个查询中的年份从该结果中选择有效记录。

select name,id1,id2,max(effdate) 
from [table] 
group by name,id1,id2

任何帮助将非常感激。

4

2 回答 2

1

对于这种类型的输出,您可以使用以下 qyery --

--您想检查有效日期是项目name列最大值的行,然后您可以只获取这些记录,然后我们可以将年份条件放在这些记录上。

SELECT NAME, Id1, Id2, Effdate
  FROM Table_Name t_1
 WHERE Effdate =
       (SELECT (t_2.Effdate) 
        FROM Table_Name t_2 
        WHERE t_2.NAME = t_1.NAME
        and t_2.id1 = t_1.id1
        and t_2.id2 = t_1.id2
        GROUP BY t_2.name,t_2.id1,t_2.id2)
   AND Your_Year_Variable_Value BETWEEN t_1.Yearfrom AND t_1.Yearto
于 2013-05-12T11:42:29.130 回答
1

目前尚不清楚这两种说法是否存在冲突。我认为它们存在冲突,我将在下面的代码中使用语句 1。

[1.] 我需要的是给定年份,选择具有不同 ID1+ID2+Name 列和最大(最近)有效日期(以 YYYYMMDD 格式,存储为整数)的记录,上述年份介于 YearFrom 之间和 YearTo 范围。

[2.] 在这种情况下,项目 1 将不会被退回,因为项目 1 的最新记录的范围是 2009-2013。

我会说第 1 项不会被退回,因为它没有 2008 年的信息。如果它确实有 2008 年的信息,则无论是否碰巧有更新的数据,都应该按照上面的语句 1 返回。


如果你扩展你的表格,让每一年单独出现在一行中,而不是像 2002-2005 这样的范围内暗示,这非常简单。下面的查询在 PostgreSQL 中;您应该只需将第一个公用表表达式替换为等效的 DB2 表达式即可生成数字表(或使用实际的数字表),并修正 CTE 语法。(DB2 的 CTE 语法是独一无二的。)

with years as (
  select generate_series(2000, 2020) as year
),
expanded_table1 as (
  select id1, id2, name, year, yearfrom, yearto, effdate
  from Table1
  inner join years on years.year between YearFrom and YearTo
)
select id1, id2, name, year, max(effdate)
from expanded_table1
where year = 2008
group by id1, id2, name, year

解释

此查询(第一个 CTE)生成一系列整数,表示我们可能感兴趣的所有年份。更强大的解决方案可能会从您的表中为数字生成器选择最小和最大年份,而不是使用整数文字。

select generate_series(2000, 2020) as year;

YEAR
--
2000
2001
2002
...
2020

通过将该表与您的表连接起来,我们可以将范围扩展为行。

with years as (
  select generate_series(2000, 2020) as year
)
select id1, id2, name, year, yearfrom, yearto, effdate
from Table1
inner join years on years.year between YearFrom and YearTo
order by id1, id2, name, year;

ID1    ID2    NAME      YEAR     YEARFROM  YEARTO   EFFDATE
--
AB     10     item1     2002     2002      2005     20091201
AB     10     item1     2003     2002      2005     20091201
AB     10     item1     2004     2002      2005     20091201
AB     10     item1     2005     2002      2005     20091201
...

以这种方式准备好基础后,为给定年份的 id1、id2、name 的每个不同组合查找最大有效日期的查询只是一个带有 WHERE 子句的简单 GROUP BY。

with years as (
  select generate_series(2000, 2020) as year
),
expanded_table1 as (
  select id1, id2, name, year, yearfrom, yearto, effdate
  from Table1
  inner join years on years.year between YearFrom and YearTo
)
select id1, id2, name, year, max(effdate)
from expanded_table1
where year = 2011
group by id1, id2, name, year

ID1    ID2    NAME      YEAR     MAX
--
AB     10     item1     2011     20100301
XX     20     item2     2011     20090912
于 2013-05-12T13:12:36.370 回答