1

現在、私は以下のようなテーブルを持っています:

U_ID SPOUSEDOB   FCHILDDOB   SCHILDDOB   ChangeDate
1    20/01/1980  01/01/1900  01/01/1900  01/01/2000
2    20/01/1950  20/01/1970  01/01/1900  01/01/2000
3    20/01/1960  20/01/1990  20/01/1995  01/01/2000
1    20/01/1980  20/01/1995  01/01/1900  01/01/2005
1    20/01/1980  20/01/1995  20/01/2006  01/01/2010

配偶者/子供がいないことを意味する1900年1月1日の日付。このテーブルを次のように変換したいと思います。

Member_ID  U_ID  Relation DOB         ChangeDate
1          1     Spouse   20/01/1980  01/01/2000
2          2     Spouse   20/01/1950  01/01/2000
3          2     Child    20/01/1970  01/01/2000
4          3     Spouse   20/01/1960  01/01/2000
5          3     Child    20/01/1990  01/01/2000
6          3     Child    20/01/1995  01/01/2000
7          1     Child    20/01/1995  01/01/2005
8          1     Child    20/01/2006  01/01/2010

しかし、この表は、特定の時間(2006年1月1日)および(2011年1月1日)にこの質問に答える最良の方法を提供できませんでした。ユーザー1には何人の子供がいましたか?答えは1と2になります。また、テーブル1からテーブル2に変換するのも難しいので、同じuser_idに対して新しい行を作成する方法に固執しています。この状況を改善する方法、またはテーブルを変換する際の問題を解決する方法について何かアイデアはありますか?ヘルプは本当にありがたいです。前もって感謝します。

4

3 に答える 3

1

これにより、テーブルが最初の形式から2番目の形式に変換されます。

SELECT
  U_ID,
  'Spouse' Relation,
  Spousedob DOB,
  MIN(STR_TO_DATE(ChangeDate, '%d/%m/%Y')) ChangeDate
FROM
  yourtable
WHERE
  Spousedob != '01/01/1900'
GROUP BY U_ID
UNION ALL
SELECT
  U_ID,
  'Child' Relation,
  FCHILDDOB DOB,
  MIN(STR_TO_DATE(ChangeDate, '%d/%m/%Y')) ChangeDate
FROM
  yourtable
WHERE FCHILDDOB != '01/01/1900'
GROUP BY U_ID
UNION ALL
SELECT
  U_ID,
  'Child' Relation,
  SCHILDDOB DOB,
  MIN(STR_TO_DATE(ChangeDate, '%d/%m/%Y')) ChangeDate
FROM yourtable
WHERE SCHILDDOB != '01/01/1900'
GROUP BY U_ID
ORDER BY ChangeDate, U_ID

しかし、あなたの質問に答えるために、あなたはこのクエリを使うことができます:

SELECT (FCHILDDOB!='01/01/1900')+(SCHILDDOB!='01/01/1900')
FROM yourtable
WHERE
  (U_ID, ChangeDate) IN (
    SELECT U_ID, MAX(ChangeDate)
    FROM yourtable
    WHERE
      U_ID=1 AND MIN(STR_TO_DATE(ChangeDate, '%d/%m/%Y'))<'2011-01-01')

(私はあなたの日付がvarcharとして保存されていると考えており、STR_TO_DATEを使用して日付に変換しています)

編集

yourtable2次のコマンドを使用して、列(Member_ID auto_increment、U_ID、Relation、DOB、ChangeDate)を含むテーブルを作成し、からyourtableにすべてのデータを挿入できますyourtable2

INSERT INTO yourtable2 (U_ID, Relation, DOB, ChangeDate)
SELECT ... --- the select query above
ORDER BY ChangeDate, DOB, U_ID

次に、使用できる子の名前を数えます。

SELECT COUNT(*)
FROM   yourtable2
WHERE  Relation='Child'
       AND U_ID=1
       AND ChangeDate <= '2011-01-01'

こちらのフィドルをご覧ください。

于 2013-03-20T11:49:53.170 に答える
1

開始テーブルの関係がわからないため、これは機能しません。ただし、単純な古いSASデータステップコードを使用して別の解決策を見つけるのに役立つ場合があります。

data have;
   input U_ID SPOUSEDOB :ddmmyy10. FCHILDDOB :ddmmyy10.  
         SCHILDDOB :ddmmyy10. ChangeDate :ddmmyy10.;
datalines;
1    20/01/1980  01/01/1900  01/01/1900  01/01/2000
2    20/01/1950  20/01/1970  01/01/1900  01/01/2000
3    20/01/1960  20/01/1990  20/01/1995  01/01/2000
1    20/01/1980  20/01/1995  01/01/1900  01/01/2005
1    20/01/1980  20/01/1995  20/01/2006  01/01/2010
run;
data want(keep=Member_ID U_ID Relation DOB ChangeDate);
   attrib Member_ID  length=8;
   attrib U_ID       length=8;
   attrib Relation   length=$6;
   attrib DOB        length=8 format=ddmmyy10.;
   attrib ChangeDate length=8 format=ddmmyy10.;
   retain Member_ID 0;

   set have;

   if _n_ = 1 or U_ID ne 1 then do;
      Member_ID + 1;
      Relation = 'Spouse';
      DOB = SPOUSEDOB;
      output;
      end;

   if FCHILDDOB ne mdy(1,1,1900) then do;
      Member_ID + 1;
      Relation = 'Child';
      DOB = FCHILDDOB;
      output;
      end;
   if SCHILDDOB ne mdy(1,1,1900) then do;
      Member_ID + 1;
      Relation = 'Child';
      DOB = SCHILDDOB;
      output;
      end;
  run;
于 2013-03-20T17:10:10.140 に答える
1

これが簡単なSASデータステップです。VNAME()を使用して関係を定義するように調整できます(他の変数の名前の付け方によって異なります)。例えば、

relation = vname(DOBs[_t]);

次に、SUBSTRなどを使用して、適切なテキストに短縮します。それ以外は、最初のHAVEデータセット内の任意の数の関係を処理するのに十分な柔軟性が必要です。

data want;
set have;
array DOBs SPOUSEDOB   FCHILDDOB   SCHILDDOB;
do _t = 1 to dim(DOBs);
  if DOBs[_t] ne '01JAN1900'd then do;
    relation=ifc(_t=1,'Spouse','Child'); *this could also be done using VNAME() to be more flexible;
    DOB=DOBs[_t];
    output;
  end;
end;
keep relation DOB ChangeDate U_ID;
format DOB Changedate Date9.;
run;

proc sort data=want;
by u_id descending relation dob changedate;
run;


data final;
set want;
by u_id descending relation dob changedate;
if first.dob;
run;

次に、特定の日付の時点で生まれた人だけを選択するように処理するには、SQLを使用する場合は、投稿されたクエリfthiellaを使用するか、次のようにSASプロシージャでフィルタリングできます。

proc means data=final;
where dob le '01JAN2006'd;
class relation;
var (whatever);
run;

または、実際のDOBではなく、フィルタリングする場合はChangeDateを使用します。

于 2013-03-20T18:19:14.700 に答える