Вложенная функция SQL IIF

Я пытаюсь сделать сложную формулу в SQL с вложенной функцией IIF. В этой формуле много IFF. Но почему-то запрос Microsoft не принимает оператор: введите здесь описание изображения

SELECT

IIF (system_Machine.Machine_omschrijving IN ('BE'),
IIF (PD_FleeceRecipe.FleeceRecipe_IntermediateLayer1Width is NULL,
IIF (PD_FleeceRecipe.FleeceRecipe_BottomLayerWidth is NULL, PD_FleeceRecipe.FleeceRecipe_IntermediateLayer2Width, PD_FleeceRecipe.FleeceRecipe_BottomLayerWidth)
,
IIF(PD_FleeceRecipe.FleeceRecipe_BottomLayerWidth is NULL,
IIF(PD_FleeceRecipe.FleeceRecipe_IntermediateLayer1Width is NULL, PD_FleeceRecipe.FleeceRecipe_BottomLayerWidth, PD_FleeceRecipe.FleeceRecipe_IntermediateLayer1Width)
,
PD_FleeceRecipe.FleeceRecipe_BottomLayerWidth-PD_FleeceRecipe.FleeceRecipe_IntermediateLayer2Width+PD_FleeceRecipe.FleeceRecipe_IntermediateLayer1Width-PD_FleeceRecipe.FleeceRecipe_IntermediateLayer2Width)
)))
[res] ,

PD_Packaging.Packaging_Itemnr,  
PD_Packaging.Packaging_Description,  
PD_Packaging.Packaging_Width,   
PD_Packaging.Packaging_Weight,   
PD_Packaging.Packaging_Weightgm2,   
PD_Packaging.Packaging_Overlap,   
PD_Packaging.Packaging_Verstrekking,   
PD_Packaging.Packaging_CategoryName,    
PD_Main.Main_StatusID,  
PD_Main.Main_Itemnr,
system_Machine.Machine_omschrijving,   
PD_Main.Main_Product,   
PD_Main.Main_WidthTobeInvoiced,  
PD_Main.Main_AssemblingRollDiameter,  
PD_Main.Main_AssemblingRollLength,  
PD_Main.Main_LabelArea,    
PD_FleeceRecipe.FleeceRecipe_IntermediateLayer1Width,  
PD_FleeceRecipe.FleeceRecipe_IntermediateLayer2Width,  
PD_FleeceRecipe.FleeceRecipe_BottomLayerWidth

FROM testsystemOBB.dbo.PD_Packaging PD_Packaging    
LEFT OUTER JOIN testsystemOBB.dbo.PD_Main
ON PD_Packaging.Packaging_ID = PD_Main.Main_AssemblingPackagingSingleRollID AND PD_Main.Main_StatusID = 2

LEFT OUTER JOIN testsystemOBB.dbo.PD_FleeceRecipe  
ON PD_Main.Main_ID = PD_FleeceRecipe.FleeceRecipe_MainID AND FleeceRecipe_Preferred = 1    

LEFT OUTER JOIN testsystemOBB.dbo.BOM_Results  
ON PD_Main.Main_Itemnr = BOM_Results.Item_Number

LEFT OUTER JOIN testsystemOBB.dbo.system_Machine  
ON BOM_Results.SelMachineID = system_Machine.Machine_id

WHERE (PD_Packaging.Packaging_CategoryName='STRETCH')  AND (PD_Main.Main_Itemnr = 406181)

Я также попробовал небольшой пример с другой функцией ISNULL, но результат: «Неожиданный RES за списком столбцов select. Я не понимаю, в чем моя ошибка.

SELECT

IIF (system_Machine.Machine_omschrijving IN ('BE'),
IIF (ISNULL(FleeceRecipe_IntermediateLayer1Width), 3,4))

[res] ,

PD_Packaging.Packaging_Itemnr,  
PD_Packaging.Packaging_Description,  
PD_Packaging.Packaging_Width,   
PD_Packaging.Packaging_Weight,   
PD_Packaging.Packaging_Weightgm2,   
PD_Packaging.Packaging_Overlap,   
PD_Packaging.Packaging_Verstrekking,   
PD_Packaging.Packaging_CategoryName,    
PD_Main.Main_StatusID,  
PD_Main.Main_Itemnr,
system_Machine.Machine_omschrijving,   
PD_Main.Main_Product,   
PD_Main.Main_WidthTobeInvoiced,  
PD_Main.Main_AssemblingRollDiameter,  
PD_Main.Main_AssemblingRollLength,  
PD_Main.Main_LabelArea,    
PD_FleeceRecipe.FleeceRecipe_IntermediateLayer1Width,  
PD_FleeceRecipe.FleeceRecipe_IntermediateLayer2Width,  
PD_FleeceRecipe.FleeceRecipe_BottomLayerWidth

FROM testsystemOBB.dbo.PD_Packaging PD_Packaging    
LEFT OUTER JOIN testsystemOBB.dbo.PD_Main
ON PD_Packaging.Packaging_ID = PD_Main.Main_AssemblingPackagingSingleRollID AND PD_Main.Main_StatusID = 2

LEFT OUTER JOIN testsystemOBB.dbo.PD_FleeceRecipe  
ON PD_Main.Main_ID = PD_FleeceRecipe.FleeceRecipe_MainID AND FleeceRecipe_Preferred = 1    

LEFT OUTER JOIN testsystemOBB.dbo.BOM_Results  
ON PD_Main.Main_Itemnr = BOM_Results.Item_Number

LEFT OUTER JOIN testsystemOBB.dbo.system_Machine  
ON BOM_Results.SelMachineID = system_Machine.Machine_id

WHERE (PD_Packaging.Packaging_CategoryName='STRETCH')  AND (PD_Main.Main_Itemnr = 406181)

введите здесь описание изображения


person MTH    schedule 11.03.2020    source источник
comment
Не могли бы вы перевести сообщения об ошибках на английский?   -  person Salman A    schedule 11.03.2020
comment
Я вижу отсутствующий третий параметр для внешнего IIF, что означает, что это просто синтаксическая ошибка.   -  person Salman A    schedule 11.03.2020
comment
Сообщение на втором снимке экрана = Unexpexted [Res] за списком столбцов SELECT. Я пробовал также функцию SWITCH, но без положительного результата. Может что-то в синтаксисе не так, но я этого не вижу. Второй пример прост и должен работать, но это не так.   -  person MTH    schedule 11.03.2020


Ответы (2)


У вас есть синтаксические ошибки. IIF состоит из трех обязательных частей:
выражение условия, истинное значение и ложное значение.

Вам не хватает ложного выражения в самой внешней функции iif в обоих запросах, а также запятой после этого (и в первом запросе слишком много закрывающих скобок)

В вашем первом запросе:

SELECT

IIF (
    system_Machine.Machine_omschrijving IN ('BE'),
    IIF(PD_FleeceRecipe.FleeceRecipe_IntermediateLayer1Width is NULL,
        IIF (PD_FleeceRecipe.FleeceRecipe_BottomLayerWidth is NULL, 
             PD_FleeceRecipe.FleeceRecipe_IntermediateLayer2Width, 
             PD_FleeceRecipe.FleeceRecipe_BottomLayerWidth
        ),
        IIF(PD_FleeceRecipe.FleeceRecipe_BottomLayerWidth is NULL,
            IIF(PD_FleeceRecipe.FleeceRecipe_IntermediateLayer1Width is NULL, 
                PD_FleeceRecipe.FleeceRecipe_BottomLayerWidth, 
                PD_FleeceRecipe.FleeceRecipe_IntermediateLayer1Width
            ),
            PD_FleeceRecipe.FleeceRecipe_BottomLayerWidth - PD_FleeceRecipe.FleeceRecipe_IntermediateLayer2Width + PD_FleeceRecipe.FleeceRecipe_IntermediateLayer1Width - PD_FleeceRecipe.FleeceRecipe_IntermediateLayer2Width
        )
    )
/* Missing a false value here...*/) 
-- ) this closing parenthesis shouldn't be here. Instead, there should be a comma.
[res] ,

А что касается второго запроса:

SELECT

IIF (system_Machine.Machine_omschrijving IN ('BE'),
    IIF (ISNULL(FleeceRecipe_IntermediateLayer1Width), 3,4)
    -- missing a false value here
) -- missing a comma here

[res] ,
person Zohar Peled    schedule 11.03.2020

Вместо этого попробуйте использовать вложенные операторы case.

Я заметил одну вещь: другого варианта нет, если Machine_omschrijving IN ('BE') не оценивается как true.

В операторах case ELSE не является обязательным. Если не вернуть, он просто вернет NULL

SELECT
    case 
        when system_Machine.Machine_omschrijving IN ('BE') 
        Then
            case 
                when PD_FleeceRecipe.FleeceRecipe_IntermediateLayer1Width is NULL
                Then
                    Case 
                        when PD_FleeceRecipe.FleeceRecipe_BottomLayerWidth is NULL
                        Then PD_FleeceRecipe.FleeceRecipe_IntermediateLayer2Width
                        Else PD_FleeceRecipe.FleeceRecipe_BottomLayerWidth
                    End
                Else
                    Case 
                        when PD_FleeceRecipe.FleeceRecipe_BottomLayerWidth is NULL
                        then
                            case 
                                when PD_FleeceRecipe.FleeceRecipe_IntermediateLayer1Width is NULL
                                then PD_FleeceRecipe.FleeceRecipe_BottomLayerWidth
                                Else PD_FleeceRecipe.FleeceRecipe_IntermediateLayer1Width
                            End
                        Else (PD_FleeceRecipe.FleeceRecipe_BottomLayerWidth-PD_FleeceRecipe.FleeceRecipe_IntermediateLayer2Width+PD_FleeceRecipe.FleeceRecipe_IntermediateLayer1Width-PD_FleeceRecipe.FleeceRecipe_IntermediateLayer2Width)
                    End
            End
    End
    [res] ,


    PD_Packaging.Packaging_Itemnr,  
    PD_Packaging.Packaging_Description,  
    PD_Packaging.Packaging_Width,   
    PD_Packaging.Packaging_Weight,   
    PD_Packaging.Packaging_Weightgm2,   
    PD_Packaging.Packaging_Overlap,   
    PD_Packaging.Packaging_Verstrekking,   
    PD_Packaging.Packaging_CategoryName,    
    PD_Main.Main_StatusID,  
    PD_Main.Main_Itemnr,
    system_Machine.Machine_omschrijving,   
    PD_Main.Main_Product,   
    PD_Main.Main_WidthTobeInvoiced,  
    PD_Main.Main_AssemblingRollDiameter,  
    PD_Main.Main_AssemblingRollLength,  
    PD_Main.Main_LabelArea,    
    PD_FleeceRecipe.FleeceRecipe_IntermediateLayer1Width,  
    PD_FleeceRecipe.FleeceRecipe_IntermediateLayer2Width,  
    PD_FleeceRecipe.FleeceRecipe_BottomLayerWidth

FROM 
    testsystemOBB.dbo.PD_Packaging PD_Packaging    
    LEFT OUTER JOIN testsystemOBB.dbo.PD_Main ON PD_Packaging.Packaging_ID = PD_Main.Main_AssemblingPackagingSingleRollID AND PD_Main.Main_StatusID = 2
    LEFT OUTER JOIN testsystemOBB.dbo.PD_FleeceRecipe  ON PD_Main.Main_ID = PD_FleeceRecipe.FleeceRecipe_MainID AND FleeceRecipe_Preferred = 1    
    LEFT OUTER JOIN testsystemOBB.dbo.BOM_Results  ON PD_Main.Main_Itemnr = BOM_Results.Item_Number
    LEFT OUTER JOIN testsystemOBB.dbo.system_Machine  ON BOM_Results.SelMachineID = system_Machine.Machine_id

WHERE 
    (PD_Packaging.Packaging_CategoryName='STRETCH')  AND (PD_Main.Main_Itemnr = 406181)
person OWSam    schedule 11.03.2020
comment
Еще нужна запятая после последней end - person Zohar Peled; 11.03.2020
comment
Он возвращает имя столбца как [res]. Я предполагаю, что именно это имел в виду ОП. - person OWSam; 11.03.2020
comment
Я думаю, что вы правы насчет этого. Виноват. еще одна причина использовать AS для псевдонимов - чтобы избежать путаницы - person Zohar Peled; 11.03.2020