为什么SQL中没有Product聚合函数?
我正在寻找类似于 SUM
工作方式的 SELECT PRODUCT(table.price) FROM table GROUP BY table.sale
之类的内容。
我是否错过了文档中的某些内容,或者真的没有 PRODUCT
功能?
如果是这样,为什么不呢?
注意:我在postgres、mysql和mssql中查找了该函数,但没有找到,所以我假设所有sql都不支持它。
Im looking for something like SELECT PRODUCT(table.price) FROM table GROUP BY table.sale
similar to how SUM
works.
Have I missed something on the documentation, or is there really no PRODUCT
function?
If so, why not?
Note: I looked for the function in postgres, mysql and mssql and found none so I assumed all sql does not support it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
T-SQL 中有一个巧妙的技巧(不确定它是否是 ANSI),它允许将一组行中的字符串值连接到一个变量中。看起来它也适用于乘法:
这可能比 log/exp 解决方案在数值上更稳定。
There is a neat trick in T-SQL (not sure if it's ANSI) that allows to concatenate string values from a set of rows into one variable. It looks like it works for multiplying as well:
This can potentially be more numerically stable than the log/exp solution.
我认为这是因为没有一个编号系统能够容纳许多产品。由于数据库是为大量记录而设计的,1000 个数字的乘积将是巨大的,并且在浮点数的情况下,传播的误差将是巨大的。
另请注意,使用日志可能是一个危险的解决方案。虽然从数学上来说 log(a*b) = log(a)*log(b),但它可能不会出现在计算机中,因为我们处理的不是实数。如果您计算 2^(log(a)+log(b)) 而不是 a*b,您可能会得到意想不到的结果。例如:
SELECT 9999999999*99999999974482, EXP(LOG(9999999999)+LOG(99999999974482))
在 Sql Server 中返回
999999999644820000025518, 9.99999999644812E+23
所以我的观点就是当你尝试做这个产品时,一定要小心,并且要进行大量的测试。
I think that is because no numbering system is able to accommodate many products. As databases are designed for large number of records, a product of 1000 numbers would be super massive and in case of floating point numbers, the propagated error would be huge.
Also note that using log can be a dangerous solution. Although mathematically log(a*b) = log(a)*log(b), it might not be in computers as we are not dealing with real numbers. If you calculate 2^(log(a)+log(b)) instead of a*b, you may get unexpected results. For example:
SELECT 9999999999*99999999974482, EXP(LOG(9999999999)+LOG(99999999974482))
in Sql Server returns
999999999644820000025518, 9.99999999644812E+23
So my point is when you are trying to do the product do it carefully and test is heavily.
处理此问题的一种方法(如果您使用脚本语言)是使用 group_concat 函数。
例如,
SELECT group_concat(table.price) FROM table GROUP BY table.sale
这将返回一个字符串,其中包含同一销售值的所有价格,并以逗号分隔。
然后使用解析器可以获得每个价格,并进行乘法运算。 (在 php 中你甚至可以使用 array_reduce 函数,事实上在 php.net 手册中 你会得到一个合适的例子)。
干杯
One way to deal with this problem (if you are working in a scripting language) is to use the group_concat function.
For example,
SELECT group_concat(table.price) FROM table GROUP BY table.sale
This will return a string with all prices for the same sale value, separated by a comma.
Then with a parser you can get each price, and do a multiplication. (In php you can even use the array_reduce function, in fact in the php.net manual you get a suitable example).
Cheers
另一种方法基于以下事实:笛卡尔积的基数是特定集合的基数的乘积;-)
⚠ 警告:此示例仅供娱乐,相当学术性,请勿在生产中使用它! (除此之外,它仅适用于正整数且几乎很小的整数)⚠
Another approach based on fact that the cardinality of cartesian product is product of cardinalities of particular sets ;-)
⚠ WARNING: This example is just for fun and is rather academic, don't use it in production! (apart from the fact it's just for positive and practically small integers)⚠
该问题可以使用现代 SQL 功能(例如窗口函数和 CTE)来解决。一切都是标准 SQL,并且与基于对数的解决方案不同,不需要从整数世界切换到浮点世界,也不需要处理非正数。只需对行进行编号并在递归查询中评估产品,直到没有行为止:
由于您的问题涉及按销售列分组,所以事情变得有点复杂,但仍然可以解决:
结果:
在 Postgres 上测试。
The problem can be solved using modern SQL features such as window functions and CTEs. Everything is standard SQL and - unlike logarithm-based solutions - does not require switching from integer world to floating point world nor handling nonpositive numbers. Just number rows and evaluate product in recursive query until no row remain:
As your question involves grouping by sale column, things got little bit complicated but it's still solvable:
Result:
Tested on Postgres.
这是一个适合任何有需要的人的 Oracle 解决方案
Here is an oracle solution for anyone who needs it
对于 MSSQL,您可以使用它。它可以用于其他平台:它只是数学和对数的聚合。
取自我的回答:SQL Server 查询 - 分组乘法
For MSSQL you can use this. It can be adopted for other platforms: it's just maths and aggregates on logarithms.
Taken from my answer here: SQL Server Query - groupwise multiplication
我不知道为什么没有,但是(要多注意负数)你可以使用对数和指数来执行以下操作:-
I don't know why there isn't one, but (take more care over negative numbers) you can use logs and exponents to do:-
SQL 标准中没有
PRODUCT
设置函数。不过,它似乎是一个有价值的候选者(与 CONCATENATE 集合函数不同:它不太适合 SQL,例如生成的数据类型将涉及多值,并会在第一范数方面带来问题形式)。SQL 标准旨在整合 1990 年左右 SQL 产品的功能,并为未来的开发提供“思想领导”。简而言之,它们记录了 SQL 的作用以及 SQL 应该做什么。
PRODUCT
集合函数的缺失表明,在 1990 年,没有供应商值得将其纳入其中,并且学术界也没有兴趣将其引入标准中。当然,供应商总是寻求添加自己的功能,如今通常作为标准的扩展而不是无关紧要的。我不记得在我使用过的任何 SQL 产品中看到过
PRODUCT
集函数(甚至不需要一个函数)。无论如何,使用
log
和exp
标量函数(以及处理负值的逻辑)和SUM
set 函数,解决方法都相当简单;有关一些示例代码,请参阅 @gbn 的答案。不过,我从来不需要在业务应用程序中执行此操作。总之,我最好的猜测是 SQL 最终用户对
PRODUCT
集函数没有需求;此外,任何有学术兴趣的人都可能会发现这种解决方法是可以接受的(即不会重视PRODUCT
集函数提供的语法糖)。出于兴趣,SQL Server 领域确实需要新的集合函数,但窗口函数种类(以及标准 SQL 也是如此)。有关更多详细信息,包括如何参与进一步推动需求,请参阅 Itzik Ben-Gan 的博客。
There is no
PRODUCT
set function in the SQL Standard. It would appear to be a worthy candidate, though (unlike, say, aCONCATENATE
set function: it's not a good fit for SQL e.g. the resulting data type would involve multivalues and pose a problem as regards first normal form).The SQL Standards aim to consolidate functionality across SQL products circa 1990 and to provide 'thought leadership' on future development. In short, they document what SQL does and what SQL should do. The absence of
PRODUCT
set function suggests that in 1990 no vendor though it worthy of inclusion and there has been no academic interest in introducing it into the Standard.Of course, vendors always have sought to add their own functionality, these days usually as extentions to Standards rather than tangentally. I don't recall seeing a
PRODUCT
set function (or even demand for one) in any of the SQL products I've used.In any case, the work around is fairly simple using
log
andexp
scalar functions (and logic to handle negatives) with theSUM
set function; see @gbn's answer for some sample code. I've never needed to do this in a business application, though.In conclusion, my best guess is that there is no demand from SQL end users for a
PRODUCT
set function; further, that anyone with an academic interest would probably find the workaround acceptable (i.e. would not value the syntactic sugar aPRODUCT
set function would provide).Out of interest, there is indeed demand in SQL Server Land for new set functions but for those of the window function variety (and Standard SQL, too). For more details, including how to get involved in further driving demand, see Itzik Ben-Gan's blog.
您可以执行乘积聚合函数,但您必须自己进行数学计算,如下所示...
来源:http:// Productfunctionsql.codeplex.com/
You can perform a product aggregate function, but you have to do the maths yourself, like this...
Source: http://productfunctionsql.codeplex.com/