【问题标题】:Looking for DB2 SQL query寻找 DB2 SQL 查询
【发布时间】:2013-05-12 10:46:53
【问题描述】:

我对 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

任何帮助将不胜感激。

【问题讨论】:

  • 截图不可用..请提供给定示例的示例数据..
  • 抱歉,虽然屏幕截图是可见的。我现在已经编辑以包含示例数据。
  • 您的表的名称是什么?编辑:没关系,我以为我在看两张不同的桌子。
  • 文本形式的样本数据将总是比屏幕截图为您提供更多答案。感谢您加入。
  • 您的 DB2 在什么操作系统上运行?

标签: sql db2


【解决方案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

【讨论】:

  • 这不会正确地给出请求的结果。耐心等待您会看到更多答案,社区应该投票选出最佳答案。
  • @WarrenT 请描述为什么您认为此查询不会提供正确的结果?根据问题所述 - 需要在我们对对应名称具有最大 effdate 的行进行比较。我首先只记录那些记录,然后我提出了条件。为什么你觉得这没有给出正确的结果。
  • 对不起,我应该早点详细说明,但时间不够。问题说这些项目由 ID1+ID2+item 标识。它还说它正在寻找 Max(effdate)。您的查询没有解决这些因素。
  • @WarrenT 请仔细看,仅此而已。好吧,如果我们有条件用 max(effdate) 检查 effdate,那么查询将返回输出,其中 effdate 是 t_2.name..Right 的最大值?
  • 我很抱歉.. 我真的很想念 ID1+ID2+item 的那部分.. 我将相应地更改此查询。感谢您指出这一点。
【解决方案2】:

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

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

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

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


如果您扩展您的表格,让每一年单独出现在一行中,而不是像 2002-2005 这样的范围内隐含,这非常简单。下面的查询在 PostgreSQL 中;您只需要将第一个公用表表达式替换为DB2 equivalent to generate a table of numbers(或使用实际的数字表),并修复 CTE 语法。 (DB2's CTE syntax 是独一无二的。)

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-26
    • 1970-01-01
    • 1970-01-01
    • 2021-07-02
    • 2016-10-07
    • 1970-01-01
    相关资源
    最近更新 更多