1

私のデータセットは、teradata では次のようになります。

╔═══════════╦══════════╦══════╗
║ studentid ║   date   ║ days ║
╠═══════════╬══════════╬══════╣
║      1000 ║ 2/1/2017 ║   25 ║
║      1000 ║ 3/8/2017 ║   30 ║
║      1000 ║ 4/4/2017 ║   80 ║
║      1000 ║ 5/1/2017 ║   81 ║
║      1001 ║ 1/1/2017 ║   60 ║
║      1001 ║ 2/1/2017 ║   20 ║
║      1001 ║ 4/1/2017 ║   81 ║
╚═══════════╩══════════╩══════╝

最近の 2 つの日付が 80 または 81 の場合、行に 1 を示す新しい列 (フラグ) が必要です。0 でない場合。

Student 1001 の場合、最後の 2 つの日付が 80 または 81 ではないため、すべての行で 0 にする必要があります。最後の 2 つの日付を取得する必要があります。1001 には 81 がありますが、2 番目の最後の日付には 20 があるため、両方のフラグを 0 にする必要があります。

望ましい出力:

╔═══════════╦══════════╦══════╦══════╗
║ studentid ║   date   ║ days ║ flag ║
╠═══════════╬══════════╬══════╬══════╣
║      1000 ║ 2/1/2017 ║   25 ║    0 ║
║      1000 ║ 3/8/2017 ║   30 ║    0 ║
║      1000 ║ 4/4/2017 ║   80 ║    1 ║
║      1000 ║ 5/1/2017 ║   81 ║    1 ║
║      1001 ║ 1/1/2017 ║   60 ║    0 ║
║      1001 ║ 2/1/2017 ║   20 ║    0 ║
║      1001 ║ 4/1/2017 ║   81 ║    0 ║
╚═══════════╩══════════╩══════╩══════╝
4

2 に答える 2

0

最初の 2 行については、簡単なロジックを適用できます。これにより、Explain で単一のSTAT ステップが発生します。

現在の行が 1 行目の場合: この行と次の行の両方にこれらの値のいずれかが含まれているかどうかを確認します

現在の行が 2 行目の場合: この行と前の行の両方にこれらの値のいずれかが含まれているかどうかを確認します

SELECT studentid, date_, Days,
   CASE Row_Number()
        Over (PARTITION BY studentid
              ORDER BY date DESC)
      WHEN 1 
         THEN CASE WHEN Days IN (80,81)
--                    AND Min(Days) Over (PARTITION BY studentid ORDER BY date DESC ROWS BETWEEN 1 Following AND 1 Following) IN (80,81)
                    AND Lead(Days) Over (PARTITION BY studentid ORDER BY date DESC) IN (80,81)
                   THEN 1
                   ELSE 0
              END
      WHEN 2
         THEN CASE WHEN Days IN (80,81) 
--                    AND Min(Days) Over (PARTITION BY studentid ORDER BY date DESC ROWS BETWEEN 1 Preceding AND 1 Preceding) IN (80,81)
                    AND Lag(Days) Over (PARTITION BY studentid ORDER BY date DESC) IN (80,81)
                   THEN 1
                   ELSE 0
              END
      ELSE 0
   END AS flag
FROM tab

Teradata リリースがサポートされていない場合は、lead代わりにlagthenmin構文を使用してください。

ただし、このロジックを 2 行以上に適用する必要がある場合は、より一般的なアプローチが必要です。

SELECT studentid, date, Days,
   -- check if the first n rows contain only searched values
   CASE WHEN x IS NOT NULL THEN Min(x) Over (PARTITION BY studentid) ELSE 0 END AS flag
FROM
 (
   SELECT studentid, date_, Days,
      CASE
         WHEN Row_Number()
              Over (PARTITION BY studentid
                    ORDER BY date DESC) BETWEEN 1 AND 2   -- only for the first n days
         THEN CASE WHEN Days IN (80,81) THEN 1 ELSE 0 END  -- flag the searched values
      END AS x
   FROM tab AS t
 ) AS dt
于 2018-10-18T08:47:46.417 に答える