如何获得列的总和

时间:2013-03-06 11:06:50

标签: mysql sql

我在SQL Fiddle有一个示例table

CREATE TABLE my_table
(id INT NOT NULL AUTO_INCREMENT UNIQUE,
  Shot VARCHAR(4),
  sec varchar(5),
  lay VARCHAR(15) NOT NULL,
  lay_status VARCHAR(15) NOT NULL,
  blk VARCHAR(10) NOT NULL,
  blk_status VARCHAR(15) NOT NULL,
  pri VARCHAR(10) NOT NULL,
  pri_status VARCHAR(15) NOT NULL,
  ani VARCHAR(10) NOT NULL,
  ani_status VARCHAR(15) NOT NULL,
  status VARCHAR(5)
);

INSERT INTO my_table VALUES
(1,'SH01','3','1863','yes','1863','yes','P4645','yes','P4557','yes','Over'),
(2,'SH02','2.5','1863','yes','P4645','no','P4557','yes','1863','no','Over'),
(3,'SH03','0.5','P4645','yes','P4557','yes','1863','yes','1863','yes','WIP'),
(4,'SH04','1.25','1863','no','P4645','no','P4557','yes','1863','yes','RTK'),
(5,'SH05','1','1863','yes','1863','yes','P4645','yes','P4557','yes','WIP'),
(6,'SH06','6','P4557','yes','P4645','yes','P4645','yes','P4557','yes','WIP');

我使用下面的SQL来检索lay=1863的镜头。并获得秒数底部的总数。

Bu结果是错误的。任何人都可以指导我。

SELECT 
  IFNULL(Shot,'TOTAL') AS Shot
  , sec
  , lay
FROM my_table
where lay='1863'
group by shot with rollup;

总计(对于sec列)的结果应为7.75,现在显示为1

SHOT    SEC     LAY
SH01    3       1863
SH02    2.5     1863
SH04    1.25    1863
SH05    1       1863
TOTAL   7.75    

7 个答案:

答案 0 :(得分:3)

如您所愿,总和使用此查询

SELECT 
  Shot
  , sum(sec)
FROM my_table
where lay='1863'
group by shot with rollup;

GROUP BY子句允许WITH ROLLUP修饰符,该修饰符会将额外的行添加到摘要输出中。这些行表示更高级别(或超级聚合)的摘要操作

参考http://dev.mysql.com/doc/refman/5.0/en/group-by-modifiers.html

答案 1 :(得分:2)

问题是您使用的是没有聚合函数的GROUP BY。在当前查询中,您没有在sum()列上使用sec,该列是您要汇总的列。尝试使用:

SELECT 
  coalesce(Shot,'TOTAL') AS Shot
  , sum(sec) Sec
  , min(lay) lay
FROM my_table
where lay='1863'
group by shot with rollup;

请参阅SQL Fiddle with Demo

您当前的查询未执行任何聚合,因此最终汇总行不正确。

您会注意到我将lay列放在了聚合函数中。这是因为大多数数据库产品不允许将选择列表中的列排除在聚合函数内或包含在group by中。

MySQL允许这样做,因为Extension to GROUP BY

来自MySQL文档:

  

MySQL扩展了GROUP BY的使用,因此选择列表可以引用GROUP BY子句中未命名的非聚合列。 ...您可以通过避免不必要的列排序和分组来使用此功能来获得更好的性能。但是,当GROUP BY中未命名的每个非聚合列中的所有值对于每个组都相同时,这非常有用。服务器可以自由选择每个组中的任何值,因此除非它们相同,否则所选的值是不确定的。此外,添加ORDER BY子句不会影响每个组中值的选择。选择值后会对结果集进行排序,而ORDER BY不会影响服务器选择的值。

编辑:如果您想在最后一行的lay列中隐藏结果,则可以使用:

SELECT 
  coalesce(Shot,'TOTAL') AS Shot
  , sum(sec) Sec
  , case when shot is not null then min(lay) else '' end lay
FROM my_table
where lay='1863'
group by shot with rollup;

请参阅SQL Fiddle with Demo

答案 2 :(得分:1)

GROUP BY用于聚合,如果你想要总和,你必须要求总和。

SELECT
    IFNULL(Shot,'TOTAL') AS Shot
    , sum(sec)
    , max(lay)
    FROM my_table
    WHERE lay='1863'
    GROUP BY shot WITH ROLLUP;

http://sqlfiddle.com/#!2/1f61b/49

答案 3 :(得分:1)

试试这个

  SELECT 
  IFNULL(Shot,'TOTAL') AS Shot
 , sum(sec) as sec
 , lay
 FROM my_table
 where lay='1863'
 group by shot with rollup;

DEMO HERE

修改 您可以考虑计算TOTAL中的行数,因为总计也可能会计算出有多少字段。像那样

 SELECT 
 IFNULL(Shot,'TOTAL') AS Shot
 , sum(sec) as sec
 , if(Shot is null , count(*) , lay) lay
 FROM my_table
 where lay='1863'
 group by shot with rollup;

DEMO HERE

如果您想要为空,请将count(*)替换为''

答案 4 :(得分:1)

Here是由聚合

组成的MySQL内置函数列表
AVG() Return the average value of the argument
BIT_AND() Return bitwise and
BIT_OR()  Return bitwise or
BIT_XOR()(v4.1.1) Return bitwise xor
COUNT(DISTINCT)   Return the count of a number of different values
COUNT()   Return a count of the number of rows returned
GROUP_CONCAT()(v4.1)  Return a concatenated string
MAX() Return the maximum value
MIN() Return the minimum value
STD() Return the population standard deviation
STDDEV_POP()(v5.0.3)  Return the population standard deviation
STDDEV_SAMP()(v5.0.3) Return the sample standard deviation
STDDEV()  Return the population standard deviation
SUM() Return the sum
VAR_POP()(v5.0.3) Return the population standard variance
VAR_SAMP()(v5.0.3)    Return the sample variance
VARIANCE()(v4.1)  Return the population standard variance

我相信你想要SUM()

SELECT 
IFNULL(Shot,'TOTAL') AS Shot
,SUM(sec) AS sec 
, lay
FROM my_table
where lay='1863'
group by shot with rollup;

答案 5 :(得分:1)

对于TOTAL行使用'lay'列看起来不正确。除了这里是SQL将给你预期的结果:

SELECT Shot, sec, lay FROM my_table WHERE lay = '1863'
UNION
SELECT 'TOTAL' AS Shot, SUM(sec), '' AS lay FROM my_table WHERE lay = '1863';

如果列'Shot'在表格中是唯一的,例如可以使用下一个查询:

SELECT t1.Shot, t1.sec, t2.lay FROM
    (
    SELECT IFNULL(Shot, 'TOTAL') AS Shot, SUM(sec) As sec
    FROM my_table
    WHERE lay = '1863'
    GROUP BY Shot WITH ROLLUP
    ) t1
LEFT JOIN my_table t2
ON(t1.Shot = t2.shot);

以下是适用于任何情况的解决方案:

SELECT t1.Shot, t1.sec, t1.lay FROM
    (
    SELECT IFNULL(Shot, 'TOTAL') AS Shot, SUM(sec) as sec, lay
    FROM my_table
    WHERE lay = '1863'
    GROUP BY Shot, lay WITH ROLLUP
    ) t1
WHERE t1.lay IS NOT NULL OR t1.Shot = 'TOTAL';

答案 6 :(得分:0)

试试这个::

    SELECT     
    Shot,
 sec,
lay   
    FROM my_table
    where lay='1863' and Shot is not null
    group by shot with rollup

    UNION

    SELECT 
   'TOTAL' AS Shot,
 SUM(sec),
 lay
FROM my_table
 where lay='1863'
 group by shot with rollup