在SQL中有聚合运算符,如AVG,SUM,COUNT。为什么它没有乘法运算符? “MUL”或其他什么。
我想知道,Oracle,MSSQL,MySQL是否存在?如果没有,是否会出现这种行为?
答案 0 :(得分:40)
通过MUL,你的意思是逐步增加值吗?
即使有100行一些小尺寸(比如10s),你的MUL(列)也会溢出任何数据类型!由于错误/滥用的概率很高,而且使用范围非常有限,因此不需要是SQL标准。正如其他人已经表明的那样,有数学方法可以解决这个问题,就像使用标准(和常用)方法在SQL中进行棘手的计算有很多方法一样。
示例数据:
Column
1
2
4
8
COUNT : 4 items (1 for each non-null)
SUM : 1 + 2 + 4 + 8 = 15
AVG : 3.75 (SUM/COUNT)
MUL : 1 x 2 x 4 x 8 ? ( =64 )
为了完整性,Oracle,MSSQL,MySQL核心实现*
Oracle : EXP(SUM(LN(column))) or POWER(N,SUM(LOG(column, N)))
MSSQL : EXP(SUM(LOG(column))) or POWER(N,SUM(LOG(column)/LOG(N)))
MySQL : EXP(SUM(LOG(column))) or POW(N,SUM(LOG(N,column)))
<小时/> * LOG(0)和LOG(-ve)未定义。下面仅显示如何在SQL Server中处理此问题。使用相同的概念
可以找到其他SQL风格的等价物
的
create table MUL(data int)
insert MUL select 1 yourColumn union all
select 2 union all
select 4 union all
select 8 union all
select -2 union all
select 0
select CASE WHEN MIN(abs(data)) = 0 then 0 ELSE
EXP(SUM(Log(abs(nullif(data,0))))) -- the base mathematics
* round(0.5-count(nullif(sign(sign(data)+0.5),1))%2,0) -- pairs up negatives
END
from MUL
成分:
1 for >0
,0 for 0
和-1 for <0
。% 2
对负数的count()返回0.5-1=-0.5
=&gt;舍入到 -1 ),如果有一个奇数的负数0.5-0= 0.5
=&gt;轮到 1 )如果有偶数个负数答案 1 :(得分:23)
不,但你可以使用数学:)
如果yourColumn
总是大于零:
select EXP(SUM(LOG(yourColumn))) As ColumnProduct from yourTable
答案 2 :(得分:6)
我看到Oracle的答案仍然缺失,所以这里是:
SQL> with yourTable as
2 ( select 1 yourColumn from dual union all
3 select 2 from dual union all
4 select 4 from dual union all
5 select 8 from dual
6 )
7 select EXP(SUM(LN(yourColumn))) As ColumnProduct from yourTable
8 /
COLUMNPRODUCT
-------------
64
1 row selected.
的问候,
罗布。
答案 3 :(得分:1)
使用PostgreSQL,您可以创建自己的聚合函数,请参阅http://www.postgresql.org/docs/8.2/interactive/sql-createaggregate.html
要在MySQL上创建聚合函数,您需要构建.so(linux)或.dll(windows)文件。此处显示了一个示例:http://www.codeproject.com/KB/database/mygroupconcat.aspx
我不确定mssql和oracle,但我敢打赌他们也可以选择创建自定义聚合。
答案 4 :(得分:1)
随着数字的增加,你会很快打破任何数据类型。
使用LOG / EXP 棘手,因为数字&lt; = 0在使用LOG时会失败。我在this question中编写了一个处理此
的解决方案答案 5 :(得分:0)
在MS SQL中使用CTE:
CREATE TABLE Foo(Id int, Val int)
INSERT INTO Foo VALUES(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)
;WITH cte AS
(
SELECT Id, Val AS Multiply, row_number() over (order by Id) as rn
FROM Foo
WHERE Id=1
UNION ALL
SELECT ff.Id, cte.multiply*ff.Val as multiply, ff.rn FROM
(SELECT f.Id, f.Val, (row_number() over (order by f.Id)) as rn
FROM Foo f) ff
INNER JOIN cte
ON ff.rn -1= cte.rn
)
SELECT * FROM cte
答案 6 :(得分:-2)
不确定Oracle或sql-server,但在MySQL中你可以像往常一样使用*
。
mysql> select count(id), count(id)*10 from tablename;
+-----------+--------------+
| count(id) | count(id)*10 |
+-----------+--------------+
| 961 | 9610 |
+-----------+--------------+
1 row in set (0.00 sec)