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 の最新のレコードの範囲が 2009 ~ 2013 であるため、この場合、アイテム 1 は返されません。

クエリの最初の部分は正しいと思いますが、1 つのクエリで年に基づいてその結果から有効なレコードを選択する方法がわかりません。

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

これら 2 つのステートメントが矛盾しているかどうかは明らかではありません。それらは競合していると思います。以下のコードのステートメント 1 を使用します。

[1.] 特定の年に必要なのは、個別の ID1+ID2+Name 列と最大 (最新) 有効日 (YYYYMMDD 形式、整数として格納) を持つレコードを選択し、上記の年が YearFrom の間にあることです。および YearTo 範囲。

[2.] アイテム 1 の最新のレコードの範囲が 2009 年から 2013 年であるため、この場合、アイテム 1 は返されません。

アイテム 1 は、2008 年の情報がないため返されません。2008 年の情報があった場合、より新しいデータがあったかどうかに関係なく、上記のステートメント 1 に従って返されます。


2002 年から 2005 年のような範囲ではなく、各年が 1 行に表示されるように表を拡張すると、非常に単純になります。以下のクエリは 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 に答える