Я создал пользовательскую табличную функцию, которая переводит номера деталей для нашей компании. Номера деталей - это строки 15-19 di git alphanumeri c, которые дают нам различную информацию о каждом продукте. Общим сравнением будет номер автомобильного VIN. Единственное ключевое отличие состоит в том, что за эти годы структура этих чисел изменилась. Итак, один год цвет может быть символами 11 и 12, а следующий - 15 и 16. Кроме того, коды могут иметь разные значения для разных лет. Например, код «BL» может быть синим в течение одного года, а следующий - голубым. Это не идеально, но это рука, с которой мне раздали. Чтобы декодировать номера деталей, я создал пользовательскую табличную функцию. Логика c для этого изначально существовала в MS SQL. Он имеет процедурный лог c, но это не разрешено в UDTF в Snowflake. Итак, я проявил творческий подход и переписал функцию, используя CTE. Это сложно, потому что у меня есть одна таблица, которая идентифицирует структуру номера детали, и другая таблица, которая может соответствовать кодам, чтобы получить описание соответствия, основанное на любых зависимостях.
UDTF успешно запускается, когда я жестко кодирую значение: SELECT * FROM TABLE(fDecodeSmartNumber('A19GELEXXXXGRGG'));
Он также запускается успешно, если я присоединяю его к таблице, но значения не возвращаются:
SELECT sr.Company, sr.RMANum, sr.OrderNumber, d.FieldValue
FROM
tRMADataFinal sr
JOIN
table(fDecodeSmartNumber(sr.PartNumber)) d
WHERE
OrderNUmber IS NOT NULL AND
WAVLine IS NULL AND
Make IS NULL AND
FieldName = 'Make' AND
FieldValue IS NOT NULL
Однако, если я добавлю к данным RMA поля, которые не будут отфильтрованы предложением where, произойдет ошибка.
Мне любопытно, если это та же ошибка, что и здесь: https://docs.snowflake.com/en/sql-reference/udf-table-functions.html
Однако я не думаю, что обходной путь будет работать для меня, потому что мне нужно несколько условий соединения в предложении «on» моего левого соединения в функции.
Полный код функции:
CREATE OR REPLACE FUNCTION fDecodePartNumber
(
vPartNumber varchar
)
RETURNS TABLE
(
Code VARCHAR(25),
FieldName VARCHAR(200),
FieldValue VARCHAR(200)
)
AS
$$
with SNValues as (
SELECT
FieldName,
SUBSTRING(vPartNumber,Position,Length) as SNValue
FROM
SmartDecodeParts
WHERE
SNFormat = (SELECT CASE WHEN SUBSTRING(vPartNumber,2,2) >= 18 THEN '2018' ELSE '2017' END)
),
FirstResultSet as (
SELECT
V.SNValue as Code, V.FieldName, K.Dsc, K.Dependency, K.Dvalue
FROM
SNValues V
LEFT JOIN
SmartDecodeKeys K
ON
V.SNValue = K.Code AND
V.FieldName = K.FieldName
),
extColor as (
SELECT
N.Code,
REPLACE(N.FieldName,' ','') as FieldName,
Color,
STANDARD_COLOR,
C.Dependency,
C.DValue
FROM
FirstResultSet N
INNER JOIN
ColorTranslation C
ON
N.Code = C.SMART_CODE
INNER JOIN
FirstResultSet R
ON
R.Dsc = C.STANDARD_MAKE
WHERE
N.FieldName = 'Ext Color'
),
intColor as (
SELECT
N.Code,
Replace(N.FieldName,' ','') as FieldName,
Color,
STANDARD_COLOR,
C.Dependency,
C.DValue
FROM
FirstResultSet N
INNER JOIN
ColorTranslationInterior C
ON
N.Code = LEFT(C.SMART_CODE,(SELECT Length FROM SmartDecodeParts WHERE FieldName = 'Int Color' AND SNFormat = (SELECT CASE WHEN SUBSTRING(vPartNumber,2,2) >= 18 THEN '2018' ELSE '2017' END)))
INNER JOIN
FirstResultSet R
ON
R.Dsc = C.STANDARD_MAKE
WHERE
N.FieldName = 'Int Color'
),
seatColor as (
SELECT
N.Code,
REPLACE(N.FieldName,' ','') as FieldName,
Color,
STANDARD_COLOR,
C.Dependency,
C.DValue
FROM
FirstResultSet N
INNER JOIN
ColorTranslationSeat C
ON
N.Code = C.SMART_CODE
INNER JOIN
FirstResultSet R
ON
R.Dsc = C.STANDARD_MAKE
WHERE
N.FieldName = 'Seat Color'
),
NormalizedResult as (
SELECT * FROM FirstResultSet
UNION ALL
Select Code, FieldName, Color, Dependency, DValue FROM extColor
UNION ALL
SELECT Code, 'StdExtColor', STANDARD_COLOR, Dependency, DValue FROM extColor
UNION ALL
Select Code, FieldName, Color, Dependency, DValue FROM intColor
UNION ALL
SELECT Code, 'StdIntColor', STANDARD_COLOR, Dependency, DValue FROM intColor
UNION ALL
Select Code, FieldName, Color, Dependency, DValue FROM seatColor
UNION ALL
SELECT Code, 'StdSeatColor', STANDARD_COLOR, Dependency, DValue FROM seatColor
),
NormalizedWithDependencies as (
SELECT
Code, FieldName, Dsc, Dependency, m.value::string as DValue
FROM
NormalizedResult,
lateral flatten(input=>split(DValue, ',')) m
UNION ALL
SELECT
*
FROM
NormalizedResult
WHERE
DValue IS NULL
)
SELECT
D.Code,
REPLACE(D.FieldName,' ',''),
D.Dsc
FROM
NormalizedWithDependencies D
LEFT JOIN
NormalizedWithDependencies R
ON
CASE WHEN LEFT(D.DValue,1) = '!' AND SUBSTRING(D.DValue,2,LEN(R.DValue)-1) <> R.Code THEN 1
WHEN LEFT(D.DValue,1) <> '!' AND D.DValue = R.Code THEN 1
ELSE 0 END = 1 AND
D.Dependency = R.FieldName
LEFT JOIN
NormalizedWithDependencies R2
ON
CASE WHEN LEFT(R.DValue,1) = '!' AND SUBSTRING(R.DValue,2,LEN(R.DValue)-1) <> R2.Code THEN 1
WHEN LEFT(R.DValue,1) <> '!' AND R.DValue = R2.Code THEN 1
ELSE 0 END = 1 AND
R.Dependency = R2.FieldName
WHERE
(D.Dependency IS NULL OR
(R.Code IS NOT NULL AND R.Dependency IS NULL) OR
(R.Code IS NOT NULL AND R2.Code IS NOT NULL)) AND
D.FieldName <> 'Ext Color' AND
D.FieldName <> 'Int Color' AND
D.FieldName <> 'Seat Color'
$$
;
Есть идеи?