Stream Analytics UDF - использование вывода из одного UDF в другой - PullRequest
0 голосов
/ 04 июля 2018

Следующий код приводит к тому, что мое значение GT2HP равно нулю в следующих UDF:

SELECT 
    UDF.GT2HP(Collect()) as GT2HP,
    UDF.LPLPReturns(Collect()) as LPLPReturns,
    UDF.LPGasHeater(Collect()) as LPGasHeater,
    UDF.HPRaisedSW(Collect(), AVG(GT2HP)) as HPRaisedSW,
    UDF.HPCustomerDemand(Collect(), AVG(GT2HP)) as HPCustomerDemand
INTO SQLDWUKSTEAMLOSS
FROM IotHubInput
WHERE IoTHub.ConnectionDeviceId = 'uk-iotedge'
GROUP BY TumblingWindow(second, 60)

Работает следующий код:

SELECT 
    UDF.GT2HP(Collect()) as GT2HP,
    UDF.LPLPReturns(Collect()) as LPLPReturns,
    UDF.LPGasHeater(Collect()) as LPGasHeater,
    UDF.HPRaisedSW(Collect(), UDF.GT2HP(Collect())) as HPRaisedSW,
    UDF.HPCustomerDemand(Collect(), UDF.GT2HP(Collect())) as HPCustomerDemand
INTO SQLDWUKSTEAMLOSS
FROM IotHubInput
WHERE IoTHub.ConnectionDeviceId = 'uk-iotedge'
GROUP BY TumblingWindow(second, 60)

Очевидно, что второй код намного дороже в вычислительном отношении, чем первый, и я бы хотел его избежать, если это возможно.

Я хотел бы использовать выходные данные первого UDF в моем слежении за UDF, но, похоже, он обнуляется. Все операторы select выполняются параллельно, а не последовательно, что, вероятно, объясняет нулевое значение.

Есть ли способ использовать вывод одного UDF в другом UDF?

Ответы [ 2 ]

0 голосов
/ 05 июля 2018

Причина, по которой столбец GT2HP, указанный в AVG(GT2HP), всегда равен нулю, связана с семантикой SQL. Столбцы в предложении SELECT могут ссылаться только на источники, на которые ссылается FROM, и, поскольку IotHubInput.GT2HP нет - это интерпретируется как ноль.

Если вы разделите свой запрос на несколько этапов, как предположил Виньеш, в итоге вы получите первый шаг, вычисляющий COLLECT в течение 60-секундного окна:

SELECT Collect() AS c
WHERE IoTHub.ConnectionDeviceId = 'uk-iotedge'
FROM IotHubInput
GROUP BY TumblingWindow(second, 60)

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

Так что AVG в AVG (GT2HP) не нужен. Второй шаг тогда будет:

SELECT
    c,
    GT2HP = UDF.GT2HP(c)
FROM step1

Давайте назовем этот шаг step2. Теперь окончательный выбор будет:

SELECT 
    GT2HP,
    UDF.LPLPReturns(c) as LPLPReturns,
    UDF.LPGasHeater(c) as LPGasHeater,
    UDF.HPRaisedSW(c, GT2HP) as HPRaisedSW,
    UDF.HPCustomerDemand(c, GT2HP) as HPCustomerDemand
INTO SQLDWUKSTEAMLOSS
FROM step2

И все это вместе:

WITH step1 AS (
    SELECT Collect() AS c
    WHERE IoTHub.ConnectionDeviceId = 'uk-iotedge'
    FROM IotHubInput
    GROUP BY TumblingWindow(second, 60)
),
step2 AS (
    SELECT
        c,
        GT2HP = UDF.GT2HP(c)
    FROM step1
)

SELECT 
    GT2HP,
    UDF.LPLPReturns(c) as LPLPReturns,
    UDF.LPGasHeater(c) as LPGasHeater,
    UDF.HPRaisedSW(c, GT2HP) as HPRaisedSW,
    UDF.HPCustomerDemand(c, GT2HP) as HPCustomerDemand
INTO SQLDWUKSTEAMLOSS
FROM step2
0 голосов
/ 05 июля 2018

Вы можете написать это как два утверждения. Сначала выбирают Collect () и avg () с группой по. Второй выбор использует результаты для вызова UDF.

...