WHERE子句中的IIF中的NOT IN子句

时间:2016-06-27 18:40:34

标签: tsql

我希望做这样的事情:

CREATE FUNCTION [Aftermarket].[ft_Filter_V41_HubAssembly_AxleStudThreads_DEV] (
    @SearchTokens                    dbo.SearchTokenTableType      READONLY,
    @AftermarketHubAssemblyNumbers   dbo.ConMetPartNumberTableType READONLY,
    @TruckCompartmentIds             dbo.IntegerTableType          READONLY,
    @TruckMakeIds                    dbo.IntegerTableType          READONLY,
    @AxleNameIds                     dbo.IntegerTableType          READONLY,
    @GrossAxleWeightRatingRangeIds   dbo.IntegerTableType          READONLY,
    @AxleStudThreadIds               dbo.IntegerTableType          READONLY,
    @WheelMaterialStudLengthClassIds dbo.IntegerTableType          READONLY,
    @HubCastingMaterialTypeIds       dbo.IntegerTableType          READONLY,
    @HubAssemblyTypeIds              dbo.IntegerTableType          READONLY,
    @ExcludeProvidedValues BIT = 1
)
RETURNS TABLE
RETURN
    SELECT DISTINCT v.AxleStudThreadId AS Id,
    CASE v.AxleStudThreadId WHEN 0 THEN N'—' ELSE th.ThreadDesignation END AS Designation,
    bt.DiameterValue AS DiameterInch,
    CASE v.AxleStudThreadId WHEN 0 THEN N'—'
                            WHEN 6 THEN N'3/4'
                            WHEN 8 THEN N'5/8'
                            ELSE th.ThreadDesignation
                            END AS NominalDiameter
    FROM Aftermarket.vFilters_V3_HubAssemblies AS v
    JOIN Stud.Threads AS th ON v.AxleStudThreadId = th.Id
    JOIN Stud.BaseThreads AS bt ON th.BaseThreadId = bt.Id
    WHERE (((SELECT COUNT(PartNumber) FROM @AftermarketHubAssemblyNumbers)   = 0) OR v.HubAssemblyNumber                  IN (SELECT PartNumber FROM @AftermarketHubAssemblyNumbers ))
      AND (((SELECT COUNT(Value)      FROM @TruckCompartmentIds)             = 0) OR v.TruckCompartmentId                 IN (SELECT Value FROM @TruckCompartmentIds                ))
      AND (((SELECT COUNT(Value)      FROM @TruckMakeIds)                    = 0) OR v.TruckMakeId                        IN (SELECT Value FROM @TruckMakeIds                       ))
      AND (((SELECT COUNT(Value)      FROM @AxleNameIds)                     = 0) OR v.AxleNameId                         IN (SELECT Value FROM @AxleNameIds                        ))
      AND (((SELECT COUNT(Value)      FROM @GrossAxleWeightRatingRangeIds)   = 0) OR v.GawrRangeId                        IN (SELECT Value FROM @GrossAxleWeightRatingRangeIds      ))

      AND (((SELECT COUNT(Value) FROM @AxleStudThreadIds) = 0) OR IIF(@ExcludeProvidedValues = 1,
                                                                            v.AxleStudThreadId NOT IN (SELECT Value FROM @AxleStudThreadIds),
                                                                            v.AxleStudThreadId IN (SELECT Value FROM @AxleStudThreadIds))
                                                                      )

      AND (((SELECT COUNT(Value)      FROM @WheelMaterialStudLengthClassIds) = 0) OR v.WheelMaterialStudLengthClassId     IN (SELECT Value FROM @WheelMaterialStudLengthClassIds    ))
      AND (((SELECT COUNT(Value)      FROM @HubCastingMaterialTypeIds)       = 0) OR v.HubCastingMaterialTypeId           IN (SELECT Value FROM @HubCastingMaterialTypeIds          ))
      AND (((SELECT COUNT(Value)      FROM @HubAssemblyTypeIds)              = 0) OR v.HubAssemblyTypeId                  IN (SELECT Value FROM @HubAssemblyTypeIds                 ))
      AND ((SELECT COUNT(Token)
            FROM @SearchTokens
            WHERE ((LEN(Token) > 0) AND ((CAST(CHARINDEX(Token, th.ThreadDesignation) AS INT) > 0)))) = (SELECT COUNT(Token) FROM @SearchTokens WHERE LEN(Token) > 0))

这是无效的T-SQL语法。我如何表达 WHERE ... IIF(cond,Field NOT IN ...)的想法才能达到同样的效果?

IIF(@ExcludeProvidedValues = 1,
        v.AxleStudThreadId NOT IN (SELECT Value FROM @AxleStudThreadIds),
        v.AxleStudThreadId IN (SELECT Value FROM @AxleStudThreadIds))
    )

2 个答案:

答案 0 :(得分:0)

替换:

OR IIF(@ExcludeProvidedValues=1, v.AxleStudThreadId NOT IN (SELECT Value FROM @AxleStudThreadIds), 1)

使用:

1 = Case when @ExcludeProvidedValues=1 and v.AxleStudThreadId NOT IN (SELECT Value FROM @AxleStudThreadIds) then 1 else 0 end

答案 1 :(得分:0)

以下子句可以解决问题

  AND (
       ((SELECT COUNT(Value) FROM @AxleStudThreadIds) = 0)
    OR ((@ExcludeProvidedValues = 0) AND v.AxleStudThreadId IN (SELECT Value FROM @AxleStudThreadIds))
    OR ((@ExcludeProvidedValues = 1) AND v.AxleStudThreadId NOT IN (SELECT Value FROM @AxleStudThreadIds))
  )

这是完整的UDF定义:

ALTER FUNCTION [Aftermarket].[ft_Filter_V41_HubAssembly_AxleStudThreads_DEV] (
    @SearchTokens                    dbo.SearchTokenTableType      READONLY,
    @AftermarketHubAssemblyNumbers   dbo.ConMetPartNumberTableType READONLY,
    @TruckCompartmentIds             dbo.IntegerTableType          READONLY,
    @TruckMakeIds                    dbo.IntegerTableType          READONLY,
    @AxleNameIds                     dbo.IntegerTableType          READONLY,
    @GrossAxleWeightRatingRangeIds   dbo.IntegerTableType          READONLY,
    @AxleStudThreadIds               dbo.IntegerTableType          READONLY,
    @WheelMaterialStudLengthClassIds dbo.IntegerTableType          READONLY,
    @HubCastingMaterialTypeIds       dbo.IntegerTableType          READONLY,
    @HubAssemblyTypeIds              dbo.IntegerTableType          READONLY,
    @ExcludeProvidedValues BIT = 1
)
RETURNS TABLE
RETURN
    SELECT DISTINCT v.AxleStudThreadId AS Id,
    CASE v.AxleStudThreadId WHEN 0 THEN N'—' ELSE th.ThreadDesignation END AS Designation,
    bt.DiameterValue AS DiameterInch,
    CASE v.AxleStudThreadId WHEN 0 THEN N'—'
                            WHEN 6 THEN N'3/4'
                            WHEN 8 THEN N'5/8'
                            ELSE th.ThreadDesignation
                            END AS NominalDiameter
    FROM Aftermarket.vFilters_V3_HubAssemblies AS v
    JOIN Stud.Threads AS th ON v.AxleStudThreadId = th.Id
    JOIN Stud.BaseThreads AS bt ON th.BaseThreadId = bt.Id
    WHERE (((SELECT COUNT(PartNumber) FROM @AftermarketHubAssemblyNumbers)   = 0) OR v.HubAssemblyNumber                  IN (SELECT PartNumber FROM @AftermarketHubAssemblyNumbers ))
      AND (((SELECT COUNT(Value)      FROM @TruckCompartmentIds)             = 0) OR v.TruckCompartmentId                 IN (SELECT Value FROM @TruckCompartmentIds                ))
      AND (((SELECT COUNT(Value)      FROM @TruckMakeIds)                    = 0) OR v.TruckMakeId                        IN (SELECT Value FROM @TruckMakeIds                       ))
      AND (((SELECT COUNT(Value)      FROM @AxleNameIds)                     = 0) OR v.AxleNameId                         IN (SELECT Value FROM @AxleNameIds                        ))
      AND (((SELECT COUNT(Value)      FROM @GrossAxleWeightRatingRangeIds)   = 0) OR v.GawrRangeId                        IN (SELECT Value FROM @GrossAxleWeightRatingRangeIds      ))

      AND (
           ((SELECT COUNT(Value) FROM @AxleStudThreadIds) = 0)
        OR ((@ExcludeProvidedValues = 0) AND v.AxleStudThreadId IN (SELECT Value FROM @AxleStudThreadIds))
        OR ((@ExcludeProvidedValues = 1) AND v.AxleStudThreadId NOT IN (SELECT Value FROM @AxleStudThreadIds))
      )

      AND (((SELECT COUNT(Value)      FROM @WheelMaterialStudLengthClassIds) = 0) OR v.WheelMaterialStudLengthClassId     IN (SELECT Value FROM @WheelMaterialStudLengthClassIds    ))
      AND (((SELECT COUNT(Value)      FROM @HubCastingMaterialTypeIds)       = 0) OR v.HubCastingMaterialTypeId           IN (SELECT Value FROM @HubCastingMaterialTypeIds          ))
      AND (((SELECT COUNT(Value)      FROM @HubAssemblyTypeIds)              = 0) OR v.HubAssemblyTypeId                  IN (SELECT Value FROM @HubAssemblyTypeIds                 ))
      AND ((SELECT COUNT(Token)
            FROM @SearchTokens
            WHERE ((LEN(Token) > 0) AND ((CAST(CHARINDEX(Token, th.ThreadDesignation) AS INT) > 0)))) = (SELECT COUNT(Token) FROM @SearchTokens WHERE LEN(Token) > 0))