我有一张桌子,上面有一些数据,包括日期:
id action_type created_date data
1 action 1 20180405 03:00 ...
2 action 2 20180405 03:01 ...
3 action 1 20180405 02:58 ...
我有两个单独的索引(我无法添加另一个索引):action_type
和created_date
。我需要一个查询,该查询将选择在某些日期之间具有某些action_type
的所有条目:
-- Query 1:
declare @from_date datetime = '20180101 00:00'
,@to_date datetime = '20180301 00:00'
,@action_type varchar(20) = 'action 1'
select *
from my_table
where created_at between @from_date and @to_date
and action_type = @action_type
我正在使用此查询,只是在声明部分中更改变量值。问题是我没有同时包含日期和类型的索引,因此查询效率不高,但是我对此无能为力。
但是,有时我需要为所有日期运行查询(没有日期限制)。我不想编写其他查询,所以我正在设置@from_date = '20010101 00:00'
和@to_date = getdate()
,因为我确定所有日期都大于2001年1月1日。>
我的问题是:
1我想服务器无法“理解”所有数据都在该区域内,并且仍按日期执行搜索。我说对了,在这种情况下,不按日期运行搜索会更有效,例如:
select *
from my_table
where action_type = @action_type
2如果@from_date
为空,以下查询是否会按日期消除搜索?我的意思是,对于不需要按日期约束的情况,这比查询1更有效吗?
select *
from my_table
where (created_at between @from_date and @to_date or @from_date is null)
and action_type = @action_type
3还有没有其他写两种情况的查询方式:如果不为null,则按日期搜索;如果为null,则按日期搜索;如果不为null,则按日期搜索。会有效吗?
答案 0 :(得分:0)
我认为您可以使用union all
:
select t.*
from my_table t
where t.action_type = @action_type and @from_date is null
union all
select t.*
from my_table t
where t.action_type = @action_type and
created_at >= @from_date and created_at <= @to_date is null;
每个子查询应独立评估。我认为SQL Server足够聪明,可以识别出NULL
条件意味着没有行返回。