将功能应用于视图中的多列

时间:2018-10-08 23:46:45

标签: mysql sql function view

我有一个MYSQL视图,其中包含以下内容:

SELECT
    claim_month_id,
    claim.claim_id,
    month.month_id,
    paid_to_date - CASE WHEN (end_date > reported_to_insurer_date) 
    THEN LAG( paid_to_date, 1) OVER ( PARTITION BY claim_id ORDER BY month_id ) 
    ELSE 0 END AS paid_change,
    days_paid - CASE WHEN (end_date > reported_to_insurer_date) 
    THEN LAG( days_paid, 1) OVER ( PARTITION BY claim_id ORDER BY month_id ) 
    ELSE 0 END AS days_paid_change,
    wks_paid - CASE WHEN (end_date > reported_to_insurer_date) 
    THEN LAG( wks_paid, 1) OVER ( PARTITION BY claim_id ORDER BY month_id ) 
    ELSE 0 END AS wks_paid_change...

最后几行在一系列列上重复;有多个数值列,每个数值列都应用相同的功能。是否有某种简化SQL的方法,使它更容易阅读?自从我决定要更改有关算法的一些细节以来,它甚至更有用,该算法现在必须跨每个领域完成,而不仅仅是更改源。

我的视觉就像

SELECT
    claim_month_id,
    claim.claim_id,
    month.month_id,
    VIEWDIFF(paid_to_date) AS paid_to_date_change,
    VIEWDIFF(days_paid) AS days_paid_change,
    VIEWDIFF(wks_paid) AS wks_paid_change

以某种方式定义VIEWDIFF函数。

我的背景是函数式编程,所以我试图回到母系。我知道这是一个愚蠢的问题,但我似乎找不到合适的搜索词在这里找到答案。

1 个答案:

答案 0 :(得分:0)

我假设您正在使用MySQL 8x

有可能形成一个“派生表”,并通过别名获得引用计算列的能力:例如

select 
    *
  , paid_to_date - CASE
        WHEN end_date > reported_to_insurer_date THEN lag_paid_to_date
        ELSE 0
    END AS paid_change
  , days_paid - CASE
        WHEN end_date > reported_to_insurer_date THEN lag_days_paid
        ELSE 0
    END AS days_paid_change
  , wks_paid - CASE
        WHEN end_date > reported_to_insurer_date THEN lag_wks_paid
        ELSE 0
    END AS wks_paid_change
FROM (
    SELECT
          *
        , LAG(paid_to_date, 1) OVER (PARTITION BY claim_id ORDER BY month_id) AS lag_paid_to_date
        , LAG(days_paid, 1) OVER (PARTITION BY claim_id ORDER BY month_id)    AS lag_days_paid
        , LAG(wks_paid, 1) OVER (PARTITION BY claim_id ORDER BY month_id)     AS lag_wks_paid
    FROM x
    ) d

或者,您可以改用common table expression(cte),这使其看起来更“串行”,如逻辑术语,例如

WITH cte AS (
    SELECT
          *
        , LAG(paid_to_date, 1) OVER (PARTITION BY claim_id ORDER BY month_id) AS lag_paid_to_date
        , LAG(days_paid, 1) OVER (PARTITION BY claim_id ORDER BY month_id)    AS lag_days_paid
        , LAG(wks_paid, 1) OVER (PARTITION BY claim_id ORDER BY month_id)     AS lag_wks_paid
    FROM x
)

SELECT 
    *
  , paid_to_date - CASE
        WHEN end_date > reported_to_insurer_date THEN lag_paid_to_date
        ELSE 0
    END AS paid_change
  , days_paid - CASE
        WHEN end_date > reported_to_insurer_date THEN lag_days_paid
        ELSE 0
    END AS days_paid_change
  , wks_paid - CASE
        WHEN end_date > reported_to_insurer_date THEN lag_wks_paid
        ELSE 0
    END AS wks_paid_change
FROM cte

我个人更喜欢将cte用于特定目的(例如递归),但是越来越多地使用cte代替简单的派生表。