«Неподдерживаемый тип подзапроса не может быть оценен» с использованием двух разных сравнений дат в пользовательском интерфейсе Snowflake - PullRequest
0 голосов
/ 08 ноября 2019

В Snowflake я получаю вышеуказанную ошибку (в том, что является совершенно законным запросом) при использовании UDF следующим образом:

SELECT
  dd.date,
  person_count(dd.date) AS cnt
FROM dim_date dd
WHERE dd.date BETWEEN '2019-11-01' and '2019-11-07'

По сути, это работает:

CREATE OR REPLACE FUNCTION person_count(d date)
  RETURNS number 
  AS 
  $$
  SELECT COUNT(DISTINCT person_id) 
   FROM persons
   WHERE (deceased_date > d)
  $$;

И это приводит к ошибке:

CREATE OR REPLACE FUNCTION person_count(d date)
  RETURNS number 
  AS 
  $$
  SELECT COUNT(DISTINCT person_id) 
   FROM persons
   WHERE (deceased_date = '1901-01-01' OR deceased_date > d)
  $$;

Я пытался использовать TO_DATE в строке даты. Я пытался использовать deceased_date < '1901-01-02' и пытался преобразовать все даты в строки. Ничто не похоже на работу. Я думаю, что это может быть ошибка.

Ответы [ 3 ]

0 голосов
/ 08 ноября 2019

Проблема в том, что в предикате OR есть некоторые ограничения в поддержке подзапроса.

0 голосов
/ 08 ноября 2019

Я считаю, что UDF не имеет ничего общего с ошибкой. Похоже, что Snowflake выполняет синтаксическую подстановку во время синтаксического анализа запросов, где это возможно, и в этом случае получается:

SELECT
  dd.date,
  (SELECT COUNT(DISTINCT person_id) 
   FROM persons
   WHERE (deceased_date = '1901-01-01' OR deceased_date > dd.date)) AS cnt
FROM dim_date dd
WHERE dd.date BETWEEN '2019-11-01' and '2019-11-07';

, что приводит к точно такой же ошибке. Как упоминает Seeling Cheung , этот сбой возможен только при наличии нескольких условий WHERE.

Синтаксический анализ запросов с подзапросами (коррелированными или нет) в сочетании с фильтрацией по нескольким условиям кажется постоянной проблемой для Snowflake,например. Ошибка в дате каста ...

0 голосов
/ 08 ноября 2019

Согласен первый код работает,

create or replace table persons (person_id number, deceased_date date);
insert into persons values (1,'2019-10-01'),(1,'2019-09-01'),(2,'1901-01-01'),(3,'2019-11-04');

SELECT COUNT(DISTINCT person_id) 
    FROM persons
    WHERE (deceased_date = '1901-01-01' OR deceased_date > '2019-11-04');

CREATE OR REPLACE FUNCTION person_count(d date)
    RETURNS number 
    AS 
    $$
    SELECT COUNT(DISTINCT person_id) 
     FROM persons
     WHERE (deceased_date > d)
    $$;

 select column1 as date
    ,person_count(column1) as cnt 
 from values ('2019-11-01'), ('2019-11-02'), ('2019-11-03'), ('2019-11-04'), ('2019-11-05'), ('2019-11-06'), ('2019-11-07')
 order by 1;

Но эти альтернативы нет. СОЗДАТЬ ИЛИ ЗАМЕНИТЬ ФУНКЦИЮ person_count (дата d) ВОЗВРАЩАЕТ номер КАК $$ ВЫБРАТЬ СЧЕТ (DISTINCT person_id) ИЗ ЛИЦА, ГДЕ (deceased_date = '1901-01-01' ИЛИ ​​deceased_date> d) $$;

  CREATE OR REPLACE FUNCTION person_count(d date)
  RETURNS number 
  AS 
  $$
  SELECT COUNT(DISTINCT person_id)
  FROM (
    SELECT person_id FROM PERSONS WHERE deceased_date > d
    UNION 
    SELECT person_id FROM PERSONS WHERE deceased_date = '1901-01-01'
  )
  $$;  

Причина в том, что, когда они расширяют FUNCTION, они превращают его в коррелированный подзапрос (даже если это можно сделать как JOIN) и единственную работу с очень простыми коррелированными подзапросами,и вы не контролируете это. Мы ударились об это, когда хотим использовать ТАБЛИЦУЮ ФУНКЦИЮ в качестве справочных таблиц. В одном месте мы просто выкатили оператор CASE, чтобы избежать поиска (брутто), а в другом мы использовали UDF Javascript для выполнения поиска.

Но это по сути ошибка, поэтому я бы сообщил об этом.

...