Несколько операторов CASE не работают, когда входные значения являются NULL - PullRequest
0 голосов
/ 23 мая 2018

У меня есть этот запрос 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_date и end_date поступают в качестве входных параметров.Проблема в том, что они могут быть обнуляемыми, и пока третье и четвертое операторы WHEN не работают.

Есть ли способ упростить это маленькое безумие?Это то, как далеко я мог бы пойти со своими слабыми навыками SQL.

Ответы [ 2 ]

0 голосов
/ 24 мая 2018

Если предположить, что user_id уникально в user_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 не равно нулю, вы все равно можете использовать эту формулировку с select distinct, ноудаление distinct должно заметно улучшить производительность.

0 голосов
/ 23 мая 2018

Вы можете попробовать этот запрос.

В вашем случае вы можете использовать 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
    )
  )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...