如何获取小数的DATE_DIFF

时间:2018-11-21 00:00:42

标签: sql google-bigquery

我的朋友们从Netezza迁移到BigQuery。在Netezza中,“ month_between”函数将其返回十进制结果。同时,在BQ中date_diff始终是整数。有没有办法在BQ中获得小数输出?

their logic

1 个答案:

答案 0 :(得分:1)

您可以编写UDF:

CREATE TEMP FUNCTION months_between_impl(date_1 DATE, date_2 DATE) AS (
    CASE
      WHEN date_1 = date_2 
        THEN 0
      WHEN EXTRACT(DAY FROM DATE_ADD(date_1, INTERVAL 1 DAY)) = 1
        AND EXTRACT(DAY FROM DATE_ADD(date_2, INTERVAL 1 DAY)) = 1 
        THEN DATE_DIFF(date_1,date_2, MONTH)
      WHEN EXTRACT(DAY FROM date_1) = 1 
        AND EXTRACT(DAY FROM DATE_ADD(date_2, INTERVAL 1 DAY)) = 1 
        THEN DATE_DIFF(DATE_ADD(date_1, INTERVAL -1 DAY), date_2, MONTH) + 1/31
      ELSE DATE_DIFF(DATE_ADD(date_1, INTERVAL -1 DAY), date_2, MONTH) - 1 + EXTRACT(DAY FROM DATE_ADD(date_1, INTERVAL -1 DAY)) / 31 + (31 - EXTRACT(DAY FROM date_2) + 1) / 31
    END
  );

CREATE TEMP FUNCTION months_between(date_1 DATE, date_2 DATE) AS (
  TRUNC(months_between_impl(date_1, date_2),9)
);




WITH
  t AS (
  SELECT DATE("2005-02-02") AS from_date, DATE("2005-01-01") AS to_date, "1.032258064516129" AS Expected
  UNION ALL
  SELECT DATE("2007-03-15"), DATE("2007-02-20"), "0.838709677419354"
  UNION ALL
  SELECT DATE("2008-03-29"), DATE("2008-02-29"),  "1.0" 
  UNION ALL
  SELECT DATE("2008-03-31"), DATE("2008-02-29"),  "1.0" 
  UNION ALL
  SELECT DATE("2005-11-29"), DATE("2006-03-01"),  "-3.096774194" 
  UNION ALL
  SELECT DATE("1993-07-01"), DATE("1993-03-31"),  "3.03225806" 
  UNION ALL
  SELECT DATE("2005-03-31"), DATE("2005-01-01"),  "2.967741935" 
  UNION ALL
  SELECT DATE("2008-03-30"), DATE("2008-02-29"),  "1.032258064516129" 
)

SELECT
  from_date, to_date, expected, months_between(from_date, to_date) months_Between
FROM t;

enter image description here

  

由Mikhail添加

下面是在Netezza上的真实运行,显示上方的UDF实际上返回了完全正确的结果(由于某些原因,expected列中的数字不是Netezza真正返回的值-正确的数字位于result列之下-正如我确切提到的那样,费利佩的UDF产生了什么?

enter image description here