作为UDF结果的列的Where子句

时间:2010-07-07 16:31:03

标签: sql sql-server tsql select

我有一个用户定义的函数(例如myUDF(a,b)),它返回一个整数。

我正在尝试确保此函数只被调用一次,其结果可以用作WHERE子句中的条件:

SELECT col1, col2, col3, 
       myUDF(col1,col2) AS X
From myTable
WHERE x>0

SQL Server尝试将x检测为列,但它实际上是计算值的别名。

如何重新编写此查询,以便可以对计算值进行过滤,而不必多次执行UDF?

7 个答案:

答案 0 :(得分:7)

With Tbl AS 
(SELECT col1, col2, col3, myUDF(col1,col2) AS X  
        From table myTable  )

SELECT * FROM Tbl WHERE X > 0

答案 1 :(得分:5)

如果您使用的是SQL Server 2005及更高版本,则可以使用“交叉应用”:

Select T.col1, T.col2, FuncResult.X
From Table As T
    Cross Apply ( Select myUdf(T.col1, T.col2) As X ) As FuncResult
Where FuncResult.X > 0

答案 2 :(得分:4)

SELECT col1, col2, col3, dbo.myUDF(col1,col2) AS X 
From myTable 
WHERE dbo.myUDF(col1,col2) >0

但请注意,这会导致扫描,因为它不是SARGable

这是另一种方式

select * from(
SELECT col1, col2, col3, dbo.myUDF(col1,col2) AS X 
From myTable ) as  y 
WHERE x>0

答案 3 :(得分:2)

SQL Server不允许您通过别名引用列。您必须两次写出该列:

SELECT  col1, col2, col3, myUDF(col1,col2) AS X 
From    table myTable 
WHERE   myUDF(col1,col2) > 0

或者使用子查询:

SELECT  *
FROM    (
        SELECT col1, col2, col3, myUDF(col1,col2) AS X 
        From table myTable 
        ) as subq
WHERE   x > 0

答案 4 :(得分:1)

根据udf及其有用或经常使用的情况,您可以考虑将其作为computed column添加到表中。然后,您可以正常过滤列,而不必在查询中写出该函数。

答案 5 :(得分:0)

我不是100%肯定你在做什么,但由于x不是一个列,我会从你的SQL语句中删除它,所以你有:

SELECT col1, col2, col3, myUDF(col1,col2) AS X From myTable

然后将条件添加到您的代码中,这样您只能在x > 0

时调用它

答案 6 :(得分:0)

你的问题最好通过“With”条款回答(CTE我认为,在MSSS中)。

真正最好的问题是:我是否应该存储此计算值,或者每次查询表时重新计算每一行。

表格中有10行,总共有10行吗?

是否经常添加行?

您是否有适当的清除策略或只是让它成长?

每月只查询一次该表吗?

如果这是一个“长时间运行”的功能(即使你已经优化了地狱之后),你为什么要多次执行它?

你问了一次,但每个查询你确实要求每行一次。

将答案存储在索引或“虚拟列”中

优点:

每行计算一次。 查询时间不会线性增长。

缺点: 增加插入/更新时间

每次计算

优点:

插入/更新时间优化

缺点: 查询时间随行计数增加。 (不可扩展)

如果您每个月要查询一次,为什么要关心性能有多糟糕,请调整一些对您的操作产生重大影响的事情(非常轻微的滑稽)。

如果你没有插入一堆(取决于你的硬件)每秒的行数,那么预先花费这么多时间会产生很大的不同吗?