2010-03-22 54 views
0

我是一个SQL noob,我需要一点帮助来理解如果可能的大局,如果是的话,如何进行筛选结果集基于传递记录的某个字段的函数的返回值。基于函数的返回值筛选MySQL结果集

比方说,我有一个名为“Numbers”的表格,只有一个字段:“Value”。

我怎么能正确指定下面的“伪SQL”?:

SELECT Value FROM numbers WHERE IsPrime(Value)=true 

我可以做到这样的事情,如果是这样,在那里/我怎么把/店“IsPrime”?

我正在使用MySQL。

+1

的关键词是'UDF,或用户定义的Function'。实质上,mySQL提供了一种将插件模块中定义的函数绑定到可在SQL级别使用的名称的方法。但是,要注意的是,无论是基于内置还是基于UDF的情况下,由于需要mySQL扫描表(或基础索引)并尝试函数中找到的每个值。这种做法适用于小桌子/小流量,但通常在桌子尺寸或流量增加时成为负担。 – mjv 2010-03-22 12:56:42

回答

1

我同意extraneon,通常更好的方法是将此值存储在数据库中,而不是在where子句中进行计算。通过这种方式,您可以每行计算一次并为数据编制索引以获得更快的性能。

只要你在MySQL 5.x上,我会推荐一个存储函数,而不是UDF。您可以将IS_PRIME类型的列TINYINT添加到您的数据库,在该列上添加索引,然后使用存储的函数在插入时计算该值。如果您不想更改插入代码,您甚至可以使用before insert触发器计算IS_PRIME值。

存储的功能会是这个样子:

DELIMITER $$ 

DROP FUNCTION IF EXISTS IS_PRIME $$ 

CREATE FUNCTION IS_PRIME(P_INT BIGINT) RETURNS TINYINT 
BEGIN 
    DECLARE V_FACTOR BIGINT; 
    DECLARE V_MAX_FACTOR BIGINT; 

    SET V_FACTOR := 2; 
    SET V_MAX_FACTOR := round(sqrt(P_INT),0); 

    WHILE (V_FACTOR <= V_MAX_FACTOR) 
    DO 
    IF (P_INT % V_FACTOR) = 0 
    THEN 
     RETURN FALSE; 
    END IF; 
    SET V_FACTOR := V_FACTOR + 1; 
    END WHILE; 

    RETURN TRUE; 

END $$ 

DELIMITER ; 
1

我不知道用户定义函数什么,但我能想象,对于计算密集的功能,它可能是最好是将该值预先计算并存储在数据库中的某处。

根据数据在数据库中的存取方式,您可能需要客户端计算isPrime(如果客户端是Web服务或您自己的服务器上的应用程序,则可以进行此操作),或者可能是处理每条记录的计划作业isPrime是null或类似的东西。这不是即时的,但对于某些情况来说,它可能已经足够好了。

如果isPrime仅用于有时还可以在检索数据时对客户端上的数据进行后处理/过滤。