【问题标题】:Default value for LAG function in MariaDBMariaDB 中 LAG 函数的默认值
【发布时间】:2023-03-16 09:29:01
【问题描述】:

我正在尝试构建一个视图,该视图允许我跟踪两个连续 month_id 的付费值之间的差异。然而,当一个数字丢失时,那将是因为它是第一个条目,因此支付金额为 0。目前,我使用下面的数字来表示上一个数字,因为 [,default] 参数尚未在 MariaDB 中实现.

CASE WHEN (
    NOT(policy_agent_month.policy_agent_month_id IS NOT NULL        
    AND LAG(days_paid, 1) OVER (PARTITION BY claim_id ORDER BY month_id ) IS NULL)) THEN        
         LAG(days_paid, 1) OVER ( PARTITION BY claim_id ORDER BY month_id)        
    ELSE 
         0        
    END

我遇到的问题是我有大约 30 个变量需要应用此函数,这使我的代码不可读且非常笨重。有没有更好的解决方案?

【问题讨论】:

  • LAG() 和 LEAD() 的默认值始终是 1 条记录“后退”或“前进”...LAG(<column>)LAG(<column>, 1) 意思相同。
  • 其他版本的 SQL 中的 'default' 参数是指处理 NULL 值。目前我并没有为“距离”而苦苦挣扎。
  • 因为它接缝的标题你对它有“问题”或对此有疑问..我建议你阅读Why should I provide an MCVE for what seems to me to be a very simple SQL query?然后。
  • “其他版本的 SQL 中的 'default' 参数是指处理 NULL 值”@TheImpaler 的答案有什么问题,因为它似乎是您使用的这个“默认”值的有效解决方法之后。
  • 看起来没有什么问题。在我承诺之前,我只是先进行实施。

标签: mariadb


【解决方案1】:

为什么使用WITH

SELECT province, tot_pop,
       tot_pop - COALESCE(
              (LAG(tot_pop) OVER (ORDER BY tot_pop ASC)),
                        0) AS delta
    FROM provinces
    ORDER BY tot_pop asc;

+---------------------------+----------+---------+
| province                  | tot_pop  | delta   |
+---------------------------+----------+---------+
| Nunavut                   |    14585 |   14585 |
| Yukon                     |    21304 |    6719 |
| Northwest Territories     |    24571 |    3267 |
| Prince Edward Island      |    63071 |   38500 |
| Newfoundland and Labrador |   100761 |   37690 |
| New Brunswick             |   332715 |  231954 |
| Nova Scotia               |   471284 |  138569 |
| Saskatchewan              |   622467 |  151183 |
| Manitoba                  |   772672 |  150205 |
| Alberta                   |  2481213 | 1708541 |
| British Columbia          |  3287519 |  806306 |
| Quebec                    |  5321098 | 2033579 |
| Ontario                   | 10071458 | 4750360 |
+---------------------------+----------+---------+
13 rows in set (0.00 sec)

但是,它并不便宜(至少在 MySQL 8.0 中); 该表有 13 行,但

FLUSH STATUS;
SELECT ...
SHOW SESSION STATUS LIKE 'Handler%';
MySQL 8.0:
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Handler_read_rnd           | 89    |
| Handler_read_rnd_next      | 52    |
| Handler_write              | 26    |
  (and others)

MariaDB 10.3:
| Handler_read_rnd           | 77    |
| Handler_read_rnd_next      | 42    |
| Handler_tmp_write          | 13    |
| Handler_update             | 13    |

【讨论】:

    【解决方案2】:

    您可以在 MariaDB 10.2+ 中使用 CTE(通用表表达式)来预先计算常用表达式并命名以供以后使用:

    with
    x as ( -- first we compute the CTE that we name "x"
      select
        *,
        coalesce(
          LAG(days_paid, 1) OVER (PARTITION BY claim_id ORDER BY month_id), 
          123456
        ) as prev_month -- this expression gets the name "prev_month"
      from my_table -- or a simple/complex join here
    )
    select -- now the main query
      prev_month
    from x
    ... -- rest of your query here where "prev_month" is computed.
    

    在主查询中prev_month 有滞后值,或者默认值123456 为空。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-08
      • 2022-12-07
      • 1970-01-01
      • 2019-09-12
      • 2015-08-29
      • 2020-02-27
      • 2020-02-07
      • 2015-03-15
      相关资源
      最近更新 更多