WHERE子句中的"条件条件"(要应用的条件取决于"模式"标志)

Mat*_*lie 5 sql optimization conditional

我有一种情况,我已经用两种不同的方式解决了这个问题,但是想知道人们对选项的看法,以及他们是否还有其他选择......

系统正在处理数据的"间隔".

  • 所有数据都分配到"间隔"
  • 间隔由Fact表中的"interval_start"DATETIME表示
  • Dimenstion表保存"interval"的持续时间(对于不同的实体可以是不同的)
  • Dimension表中还有一个"mode"标志


SQL查询中需要以下规则...

模式0
如果记录条目在事实表中,则可以对其进行处理.
(无限制.)

模式1
如果"interval_start"过去,则记录仅对处理有效.(已经开始的时间间隔,但不一定完成.)

模式2
如果整个"间隔"是过去的,则记录仅对处理有效.(已完成的时间间隔.)


为此创建的第一个WHERE子句如下......

WHERE
    getDate() >=
        CASE [table].mode
            WHEN 0 THEN 0
            WHEN 1 THEN [log].interval_start
            WHEN 2 THEN [log].interval_start + [table].interval_period
            ELSE        NULL
        END
Run Code Online (Sandbox Code Playgroud)


有人担心这会使索引混淆优化条款.另一种方法是使用多个AND/OR条件.

WHERE
   ([table].mode = 0 AND getDate() >= 0)
OR ([table].mode = 1 AND getDate() >= [log].interval_start)
OR ([table].mode = 2 AND getDate() >= [log].interval_start + [table].interval_period)
Run Code Online (Sandbox Code Playgroud)


显然,哪个表现最好将取决于数据和索引等.但是,是否有人对我目前描述的"条件条件"有任何选择或替代方案?:)

干杯,垫子.

Tom*_*m H 5

怎么样:

WHERE
     interval_start <= CASE mode
                         WHEN 0 THEN '9999-12-31'
                         WHEN 1 THEN GETDATE()
                         WHEN 2 THEN GETDATE() - interval_period
                       END
Run Code Online (Sandbox Code Playgroud)


mwi*_*ahl 5

另一种选择是运行三个单独的查询并将它们联合在一起。根据您的索引和表结构,这可能会导致比将 WHERE 子句中的子句或使用 CASE 语句进行“或”运算更有效的 SQL,尽管这纯粹是在欺骗优化器。

我会测试所有三种方法并选择最适合您的一种。