当输入值为NULL时,多个CASE语句不起作用

问题描述 投票:1回答:2

我有这个SQL查询:

SET @start_date = 'a timestamp at x in time';
SET @end_date = 'a timestamp at x + y in time';

SELECT DISTINCT u.user_id
FROM user_plan u
  JOIN user_feature uf ON uf.user_plan_id = u.id
WHERE uf.status IN ('PENDING_ACTIVE', 'PENDING_INACTIVE')
  AND (
    CASE
      WHEN @start_date IS NULL AND @end_date IS NULL THEN true
      WHEN @end_date IS NOT NULL AND @end_date >= u.created_at AND @start_date IS NULL THEN true
      WHEN @start_date IS NOT NULL AND @start_date <= u.created_at AND @end_date IS NULL THEN true
      WHEN @start_date IS NOT NULL AND @end_date IS NOT NULL AND u.created_at BETWEEN @start_date AND @end_date THEN true
      ELSE false
    END
  ) = true;

start_dateend_date作为输入参数。问题是它们可以是可空的,到目前为止第三和第四个WHEN语句都不起作用。

有没有办法简化这个小小的疯狂?这是我可以用我的片段SQL技能走多远。

mysql sql
2个回答
1
投票

假设user_iduser_plan中是独一无二的,我会选择:

SELECT u.user_id
FROM user_plan u
WHERE EXISTS (SELECT 1
              FROM user_feature uf 
              WHERE uf.user_plan_id = u.id AND
                    uf.status IN ('PENDING_ACTIVE', 'PENDING_INACTIVE')
             ) AND
      (@end_date IS NULL OR @end_date >= u.created_at) AND
      (@start_date IS NULL OR @start_date <= u.created_at);

即使user_plan.user_id不是null,你仍然可以使用select distinct这个配方,但删除distinct应该是一个显着的性能改进。


1
投票

您可以尝试此查询。

在您的情况下,您可以使用OR而不是CASE WHEN表达式

SELECT DISTINCT u.user_id
FROM user_plan u
  JOIN user_feature uf ON uf.user_plan_id = u.id
WHERE uf.status IN ('PENDING_ACTIVE', 'PENDING_INACTIVE')
  AND (
    (@start_date IS NULL AND @end_date IS NULL)
    OR
    (
        @end_date IS NOT NULL AND @end_date >= u.created_at
    )
    OR
    (   
        @start_date IS NOT NULL AND @start_date <= u.created_at
    )
    OR
    (   
        @start_date IS NOT NULL AND @end_date IS NOT NULL AND u.created_at BETWEEN @start_date AND @end_date
    )
  )
© www.soinside.com 2019 - 2024. All rights reserved.