使用函数改进SQL查询

使用函数改进SQL查询,sql,tsql,sql-server-2008,Sql,Tsql,Sql Server 2008,我试图通过使用SQLServerExpress2008中的函数来提高查询的可读性。 这是我尝试做的一个例子 我有一个表,其中存储了一天中每小时的最高温度读数,然后我想选择上午8-10点之间的最高温度高于下午12-2点之间的最高温度的所有日子 下面是它的样子: DECLARE @TableA TABLE ([Date] DATE, [Time] TIME(0), HighTemp DECIMAL(6,2)); INSERT @TableA VALUES ('2011-09-10','08:0

我试图通过使用SQLServerExpress2008中的函数来提高查询的可读性。 这是我尝试做的一个例子

我有一个表,其中存储了一天中每小时的最高温度读数,然后我想选择上午8-10点之间的最高温度高于下午12-2点之间的最高温度的所有日子

下面是它的样子:

DECLARE @TableA TABLE ([Date] DATE, [Time] TIME(0), HighTemp DECIMAL(6,2)); 

INSERT @TableA VALUES 
('2011-09-10','08:00:00',38.15), 
('2011-09-10','09:00:00',38.32), 
('2011-09-10','10:00:00',38.17), 
('2011-09-10','11:00:00',38.10), 
('2011-09-10','12:00:00',38.05), 
('2011-09-10','13:00:00',38.15), 
('2011-09-10','14:00:00',38.30), 

('2011-09-11','08:00:00',38.12), 
('2011-09-11','09:00:00',38.09), 
('2011-09-11','10:00:00',38.07), 
('2011-09-11','11:00:00',38.15), 
('2011-09-11','12:00:00',38.13), 
('2011-09-11','13:00:00',38.11), 
('2011-09-11','14:00:00',38.10), 

('2011-09-12','08:00:00',38.30), 
('2011-09-12','09:00:00',38.33), 
('2011-09-12','10:00:00',38.35), 
('2011-09-12','11:00:00',38.30), 
('2011-09-12','12:00:00',38.25), 
('2011-09-12','13:00:00',38.23), 
('2011-09-12','14:00:00',38.20)

select distinct [DATE] from @TableA maintbl
where 
-- Select the high temp between 08:00:00-10:00:00
(select MAX(HighTemp) from @TableA tmptbl where tmptbl.Time >= '08:00:00' and tmptbl.Time <= '10:00:00' and maintbl.Date = tmptbl.Date)
>
-- Select the high between 12:00:00-14:00:00
(select MAX(HighTemp) from @TableA tmptbl where tmptbl.Time >= '12:00:00' and tmptbl.Time <= '14:00:00' and maintbl.Date = tmptbl.Date)
函数是这样的:

CREATE FUNCTION [dbo].[GetPeriodHigh] 
(
    @Date date,
    @From time,
    @To time
)
RETURNS decimal(6,2)
AS
BEGIN

    declare @res decimal(6,2)

    select @res = MAX(high) from MyTable
    where Time >= @from and Time <= @to and Date = @Date

    return @res
END
创建函数[dbo]。[GetPeriodHigh]
(
@日期,
@不时地,
@按时
)
返回十进制(6,2)
作为
开始
声明@res十进制(6,2)
从MyTable中选择@res=MAX(高)

其中,Time>=@from和Time进行数据访问的标量函数通常很糟糕,最好避免使用。它们不会被Optimizer扩展,这基本上会将函数查询作为嵌套循环连接的内侧来执行,而不管是否合适


更糟糕的是,您可能没有正确的索引来评估
Time>=@from和Time要提高性能,请尝试将标量值UDF重写为内联表值UDF

一些链接:


表上有哪些索引,每天有多少测量值?
CREATE FUNCTION [dbo].[GetPeriodHigh] 
(
    @Date date,
    @From time,
    @To time
)
RETURNS decimal(6,2)
AS
BEGIN

    declare @res decimal(6,2)

    select @res = MAX(high) from MyTable
    where Time >= @from and Time <= @to and Date = @Date

    return @res
END
SELECT [Date]
FROM @TableA
WHERE Time BETWEEN '08:00:00' AND '10:00:00' 
      OR Time BETWEEN '12:00:00' AND '14:00:00'
GROUP BY [Date]
HAVING MAX(CASE 
               WHEN Time BETWEEN '08:00:00' AND '10:00:00' THEN HighTemp END) > 
       MAX(CASE 
               WHEN Time BETWEEN '12:00:00' AND '14:00:00' THEN HighTemp END)