我有这个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技能走多远。
答案 0 :(得分: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
)
)
答案 1 :(得分:1)
假设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
应该是显着的性能提升。