SQL Switch/Case in 'where' 子句与 and

SQL Switch/Case in 'where' clause with and

我目前有这个查询

DECLARE @user uniqueidentifier
, @day_to_find int
, @date DATETIME = getdate()

SELECT
    @user = CAST(Value AS uniqueidentifier)
FROM BookSoreConfiguration.dbo.Config(NOLOCK)
WHERE Key = 'SuperUser.Id'

SELECT
    @day_to_find = CAST(Value AS int)
FROM BookSoreConfiguration.dbo.Config(NOLOCK)
WHERE Key = 'Returns.MaxDay'

--INSERT INTO...... //Part not copied for cleaning

    SELECT DISTINCT
        @user,
        @date,
        bd.shopping_code,
        bd.cod_gender,
        bd.book_number,
        '03',
        '01',
        '11',
        @user,
        @user,
        GETDATE(),
        GETDATE(),
        ean_code,
        15,
        bd.cod_variation,
    FROM bdo.BOOK_DATA bd WITH (NOLOCK)
-- various inner joins...
    WHERE 
    btw.num_catalog IS NOT NULL
    AND(
        (
        AND DATEDIFF(DAY, btw.sell_date, GETDATE()) >= @day_to_find
        OR (cod_catalog = '04'
        AND bd.cod_category NOT IN ('children', 'used', 'discounted'))
    AND bd.cod_state= '00'
    AND bd.cod_variation = '00'
    AND NOT EXISTS (SELECT TOP 1
        *
    FROM BOOK_RETURNS br (NOLOCK)
    WHERE br.code = bd.shopping_code
    AND br.cod_category = bd.cod_category
    AND br.book_number = bd.book_number
    AND br.cod_request_returns = 1
    AND br.num_progr_bd = bd.prog
    AND br.cod_elaboration = '103')
GO

我需要修改这部分:

AND DATEDIFF(DAY, btw.sell_date, GETDATE()) >= @day_to_find

如果bd.shopping_code是“B41”、“B74”、“BT34”则必须变成

AND DATEDIFF(DAY, btw.sell_date, GETDATE()) >= 30

在所有其他情况下,and 将保留

AND DATEDIFF(DAY, btw.sell_date, GETDATE()) >= @day_to_find

是否可以通过 switch case 来管理这两种情况,或者有其他可能的方式吗?

编辑 2022/05/13 如果我使用 UNION 会怎样?

DECLARE @user uniqueidentifier
, @day_to_find int
, @date DATETIME = getdate()

SELECT
    @user = CAST(Value AS uniqueidentifier)
FROM BookSoreConfiguration.dbo.Config(NOLOCK)
WHERE Key = 'SuperUser.Id'

SELECT
    @day_to_find = CAST(Value AS int)
FROM BookSoreConfiguration.dbo.Config(NOLOCK)
WHERE Key = 'Returns.MaxDay'

--INSERT INTO...... //Part not copied for cleaning

    SELECT DISTINCT
        @user,
        @date,
        bd.shopping_code,
        bd.cod_gender,
        bd.book_number,
        '03',
        '01',
        '11',
        @user,
        @user,
        GETDATE(),
        GETDATE(),
        ean_code,
        15,
        bd.cod_variation,
    FROM bdo.BOOK_DATA bd WITH (NOLOCK)
-- various inner joins...
    WHERE
    bd.shopping_code NOT IN ('B41', 'B74', 'BT34')
    AND btw.num_catalog IS NOT NULL
    AND(
        (
        AND DATEDIFF(DAY, btw.sell_date, GETDATE()) >= @day_to_find
        OR (cod_catalog = '04'
        AND bd.cod_category NOT IN ('children', 'used', 'discounted'))
    AND bd.cod_state= '00'
    AND bd.cod_variation = '00'
    AND NOT EXISTS (SELECT TOP 1
        *
    FROM BOOK_RETURNS br (NOLOCK)
    WHERE br.code = bd.shopping_code
    AND br.cod_category = bd.cod_category
    AND br.book_number = bd.book_number
    AND br.cod_request_returns = 1
    AND br.num_progr_bd = bd.prog
    AND br.cod_elaboration = '103')
    
    UNION
    SELECT DISTINCT
        @user,
        @date,
        bd.shopping_code,
        bd.cod_gender,
        bd.book_number,
        '03',
        '01',
        '11',
        @user,
        @user,
        GETDATE(),
        GETDATE(),
        ean_code,
        15,
        bd.cod_variation,
    FROM bdo.BOOK_DATA bd WITH (NOLOCK)
-- various inner joins...
    WHERE
    bd.shopping_code IN ('B41', 'B74', 'BT34')
    AND btw.num_catalog IS NOT NULL
    AND(
        (
        AND DATEDIFF(DAY, btw.sell_date, GETDATE()) >= 30
        OR (cod_catalog = '04'
        AND bd.cod_category NOT IN ('children', 'used', 'discounted'))
    AND bd.cod_state= '00'
    AND bd.cod_variation = '00'
    AND NOT EXISTS (SELECT TOP 1
        *
    FROM BOOK_RETURNS br (NOLOCK)
    WHERE br.code = bd.shopping_code
    AND br.cod_category = bd.cod_category
    AND br.book_number = bd.book_number
    AND br.cod_request_returns = 1
    AND br.num_progr_bd = bd.prog
    AND br.cod_elaboration = '103')
GO
WHERE
    (
        bd.shopping_code IN ('B41', 'B74', 'BT34') AND DATEDIFF(DAY, btw.sell_date, GETDATE()) >= 30
        OR
        DATEDIFF(DAY, btw.sell_date, GETDATE()) >= @day_to_find
     )
     AND ...

由于左边部分保持不变,只有值可以不同,您可以尝试以下方法(CASE 'returns'右边部分的值):

AND DATEDIFF(DAY, btw.sell_date, GETDATE()) >= 
  CASE
    WHEN bd.shopping_code IN ('B41', 'B74', 'BT34') THEN 30
    ELSE @day_to_find
  END