在 Bigquery 中给出两个值("then" 和 "else" 中的一个)的 Case 语句。怎么了?

Case statement giving both values (the one in "then" and in "else" together) in Bigquery. What is wrong?

我想在 Bigquery 中创建一个标志,它 return 为真时为 1,为假时为 0。当它必须 return 为 0 的“else”值时,该语句工作正常。但是,当它满足条件时,它 return 有两行,其中包含 1 和 0。为什么会这样?

下面是使用的代码:


table AS(
  SELECT
    id,
    month,
    ROUND((text/(month_days/7)), 2) AS value
    FROM (SELECT id, extract(month FROM date) AS month,
   (32 - EXTRACT(DAY FROM DATE_ADD(DATE_TRUNC(DATE(date), MONTH), INTERVAL 31 DAY))) AS month_days,
    sum(text_sent) AS text
    FROM table1
    WHERE date BETWEEN '2020-01-01 00:00:00 UTC' AND '2020-06-30 00:00:00 UTC'
    GROUP BY 1,2,3)),
    
table_flag AS(
SELECT
id,
CASE
WHEN month = 1 AND value > 100 THEN 1
WHEN month = 2 AND value > 150 THEN 1
WHEN month = 3 AND value > 130 THEN 1
WHEN month = 4 AND value > 200 THEN 1
WHEN month = 5 AND value > 235 THEN 1
WHEN month = 6 AND value > 125 THEN 1
WHEN month = 7 AND value > 324 THEN 1
WHEN month = 8 AND value > 160 THEN 1
WHEN month = 9 AND value > 350 THEN 1
WHEN month = 10 AND value > 80 THEN 1
WHEN month = 11 AND value > 245 THEN 1
ELSE 0
END AS value_flag
FROM
table)

SELECT
  t.id,
  t.value,
  t.month,
  tf.value_flag
  FROM
  table t
 LEFT JOIN
  table_flag tf
  ON
  t.id = tf.id
  WHERE t.id IS NOT NULL
   GROUP BY 1,2,3,4
   ORDER BY 1

我也尝试过嵌套 IF,但这也不起作用:

SELECT DISTINCT(id),
(IF((month = 1 AND value > 100), 1,
(IF((month = 2 AND value > 150), 1,
(IF((month = 3 AND value > 130), 1,
(IF((month = 4 AND value > 200), 1,
(IF((month = 5 AND value > 235), 1,
(IF((month = 6 AND value > 125), 1,
(IF((month = 7 AND value > 324), 1,
(IF((month = 8 AND value > 160), 1,
(IF((month = 9 AND value > 350), 1,
(IF((month = 10 AND value > 80), 1,
(IF((month = 11 AND value > 245), 1,0))))))))))))))))))))))
AS value_flag
FROM table)

这是输出现在的样子(这不是我想要的):

enter image description here

输出完全错误。请建议替代方法(如果有的话)。

P.S.: 这是我的第一个问题,如果需要任何其他信息,请告诉我。在此先感谢您的帮助!

tabletable_flag 都有几行相同 idtable 中每一行的 BigQuery 在 table_flag 中找到多行。要删除重复项,我们可以将 month 添加到 table_flagON 子句。但是我们其实不需要最后的LEFT JOIN。试试这个:

WITH table AS(
  SELECT
    id,
    month,
    ROUND((text/(month_days/7)), 2) AS value
  FROM (
    SELECT 
      id, 
      extract(month FROM date) AS month,
      (32 - EXTRACT(DAY FROM DATE_ADD(DATE_TRUNC(DATE(date), MONTH), INTERVAL 31 DAY))) AS month_days,
      sum(text_sent) AS text
    FROM table1
    WHERE 
      date BETWEEN '2020-01-01 00:00:00 UTC' AND '2020-06-30 00:00:00 UTC'
      AND id IS NOT NULL
    GROUP BY 1,2,3
  )
)
SELECT
  id,
  value,
  month,
  CASE
    WHEN month = 1 AND value > 100 THEN 1
    WHEN month = 2 AND value > 150 THEN 1
    WHEN month = 3 AND value > 130 THEN 1
    WHEN month = 4 AND value > 200 THEN 1
    WHEN month = 5 AND value > 235 THEN 1
    WHEN month = 6 AND value > 125 THEN 1
    WHEN month = 7 AND value > 324 THEN 1
    WHEN month = 8 AND value > 160 THEN 1
    WHEN month = 9 AND value > 350 THEN 1
    WHEN month = 10 AND value > 80 THEN 1
    WHEN month = 11 AND value > 245 THEN 1
    ELSE 0
  END AS value_flag
FROM table
ORDER BY 1

或者这个:

SELECT
  id,
  month,
  ROUND((text/(month_days/7)), 2) AS value,
  CASE
    WHEN month = 1 AND ROUND((text/(month_days/7)), 2) > 100 THEN 1
    WHEN month = 2 AND ROUND((text/(month_days/7)), 2) > 150 THEN 1
    WHEN month = 3 AND ROUND((text/(month_days/7)), 2) > 130 THEN 1
    WHEN month = 4 AND ROUND((text/(month_days/7)), 2) > 200 THEN 1
    WHEN month = 5 AND ROUND((text/(month_days/7)), 2) > 235 THEN 1
    WHEN month = 6 AND ROUND((text/(month_days/7)), 2) > 125 THEN 1
    WHEN month = 7 AND ROUND((text/(month_days/7)), 2) > 324 THEN 1
    WHEN month = 8 AND ROUND((text/(month_days/7)), 2) > 160 THEN 1
    WHEN month = 9 AND ROUND((text/(month_days/7)), 2) > 350 THEN 1
    WHEN month = 10 AND ROUND((text/(month_days/7)), 2) > 80 THEN 1
    WHEN month = 11 AND ROUND((text/(month_days/7)), 2) > 245 THEN 1
    ELSE 0
  END AS value_flag
FROM (
  SELECT 
    id, 
    extract(month FROM date) AS month,
    (32 - EXTRACT(DAY FROM DATE_ADD(DATE_TRUNC(DATE(date), MONTH), INTERVAL 31 DAY))) AS month_days,
    sum(text_sent) AS text
  FROM table1
  WHERE 
    date BETWEEN '2020-01-01 00:00:00 UTC' AND '2020-06-30 00:00:00 UTC'
    AND id IS NOT NULL
  GROUP BY 1,2,3
)
ORDER BY 1