SQL 查询以识别 1 之后的 0

SQL query to identify 0 AFTER a 1

假设我有两列:DateIndicator

通常指标从 0 到 1(当数据按日期排序时)并且 我希望能够识别它是否从 1改为 0。 SQL 有没有简单的方法?

我已经在同一个 table 中聚合其他字段。如果我可以将其添加为另一个聚合(例如,不使用单独的 "where" 语句或第二次传递数据),那就太棒了。

这是我要捕捉的现象:

Date      Indicator
1/5/01    0
1/4/01    0
1/3/01    1
1/2/01    1
1/1/01    0

假设您的意思是要确定具有 1 作为其 indicator 值的任何行是否比其组中具有 0 的行具有更早的 Date作为其 indicator 值,您可以通过在汇总结果中包含适当的极端日期来识别具有该特征的组:

SELECT
  ...
  MAX(CASE indicator WHEN 0 THEN Date END) AS last_ind_0,
  MIN(CASE indicator WHEN 1 THEN Date END) AS first_ind_1,
  ...

然后您在代码中或作为另一个选择项测试 first_ind_1 是否小于 last_ind_0

这不是特定于 teradata 的答案,但是 可以 在正常 SQL 中完成。

假设序列已经是'complete',xn+1可以从xn推导出来,比如当日期是连续的并且都存在时:

SELECT date -- the 1 on the day following the 0
FROM r curr
JOIN r prev
-- join each day with the previous day
ON curr.date = dateadd(d, 1, prev.date)
WHERE curr.indicator = 1
  AND prev.indicator = 0

YMMV 关于此类查询有效使用索引的能力。

  • 如果序列不完整,可以在制作一个有序的委托序列后应用相同的序列,类似地 'complete'。

  • 这也可以使用correlated subqueries来完成,每次选择'previous max'的指标,但是.. uhg.

加入 table 反对它本身它非常通用,但大多数 SQL 方言现在支持分析函数。理想情况下,您可以使用 LAG(),但 TeraData 似乎试图支持这些中的绝对最小值,因此他们指出您使用 SUM() 结合 rows preceding

在任何方面,此方法都避免了可能代价高昂的连接并有效地处理数据中的间隙,同时最大限度地利用索引。

SELECT
  *
FROM
  yourTable   t
QUALIFY
  t.indicator
  <
  SUM(t.indicator) OVER (PARTITION BY t.somecolumn /* optional */
                             ORDER BY t.Date
                         ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING
                        )

QUALIFY 有点特定于 TeraData,但比替代方案稍微整洁一些...

SELECT
  *
FROM
(
  SELECT
    *,
    SUM(t.indicator) OVER (PARTITION BY t.somecolumn /* optional */
                               ORDER BY t.Date
                           ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING
                          )
                            AS previous_indicator
  FROM
    yourTable   t
)
  lagged
WHERE
  lagged.indicator < lagged.previous_indicator