Получение недетерминированных c результатов из WITH RECURSIVE cte - PullRequest
0 голосов
/ 13 июля 2020

Я пытаюсь создать рекурсивный CTE, который просматривает все записи для данного идентификатора и выполняет некоторые операции между упорядоченными записями. Скажем, у меня есть клиенты в банке, с которых взимается однозначно идентифицируемая комиссия, и клиент может оплатить эту комиссию любым количеством взносов:

WITH recursive payments ( 
         id
       , index
       , fees_paid
       , fees_owed
       )
  
  AS (
  
  SELECT id
       , index
       , fees_paid
       , fee_charged
    FROM table
   WHERE index = 1
    
   UNION ALL
    
  SELECT t.id
       , t.index
       , t.fees_paid
       , p.fees_owed - p.fees_paid 
    FROM table t
    JOIN payments p
      ON t.id = p.id
     AND t.index = p.index + 1
  )

  SELECT * 
    FROM payments 
ORDER BY 1,2;

Логин присоединения c кажется нормальным, но когда я присоедините вывод этого запроса к исходной таблице, я получаю недетерминированные c и неверные результаты.

Это мой первый набег на рекурсивные CTE Snowflake. Что мне не хватает в логике промежуточных результатов c, что приводит к недетерминированности здесь?

1 Ответ

0 голосов
/ 13 июля 2020

Я предполагаю, что это отредактированный код, потому что в привязке вашего CTE вы выбираете четвертый столбец fee_charged, который не существует, а затем в рекурсии вы не суммируете fees paid и другие вещи, в основном вы logi c кажется довольно странным.

Итак, создавая некоторые случайные данные, которые имеют два разных id потока для рекурсии:

create or replace table data (id number, index number, val text);
insert into data 
  select * from values (1,1,'a'),(2,1,'b')
      ,(1,2,'c'), (2,2,'d')
      ,(1,3,'e'), (2,3,'f')
      v(id, index, val);

Теперь немного изменим CTE, чтобы объедините эти строки вместе ..

WITH RECURSIVE payments AS
(
  SELECT id
       , index
       , val
    FROM data
   WHERE index = 1

  UNION ALL

  SELECT t.id
       , t.index
       , p.val || t.val as val
    FROM data t
    JOIN payments p
      ON t.id = p.id
     AND t.index = p.index + 1
)
  SELECT * 
    FROM payments 
ORDER BY 1,2;

мы получим:

ID  INDEX   VAL
1   1       a
1   2       ac
1   3       ace
2   1       b
2   2       bd
2   3       bdf

Это именно то, что я ожидал. Итак, как это связано с вашим «становится странным, когда я присоединяюсь к другим вещам» - это эфир, ваш результат CTE не такой, как вы ожидаете .. Или ваше соединение с другими вещами работает не так, как вы ожидаете, Или там - это ошибка снежинки.

Все сводится к тому, что если результаты CTE соответствуют вашим ожиданиям, создайте таблицу и присоедините ее к другой таблице, поэтому устраните некоторую форму ошибки CTE vs JOIN и для отладки, почему ваше соединение не работает.

Но если ваш вывод CTE не тот, который вы ожидаете, позвольте помочь отладить это.

...