2013-03-06 117 views
1

我有一个样本table这里在SQL小提琴。如何获得一列的总和

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的Shots。并在秒的底部得到总数。

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

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

结果在总(为秒列)应为7.75,现将其表示1

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

你的意思是错的?你想要什么结果? – 2013-03-06 11:08:12

+0

您的预期成果是什么? – 2013-03-06 11:11:00

回答

2

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

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

+0

UI不认为我们需要min(lay)lay。你能告诉我你为什么使用它吗?蚂蚁如何感谢答案,因为我学习了新的函数'coalesce' – Rao 2013-03-06 11:21:21

+0

@PBLNarasimhaRao MySQL并不要求它在一个聚合,但我添加了聚合,所以这个查询将在MySQL以外的工作。 :) – Taryn 2013-03-06 11:26:46

+0

在最后一行最后一列(躺)旁边7.75显示1863年,我不想显示。你能告诉如何避免它。 – Rao 2013-03-06 11:27:51

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 
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

+0

在7.75旁边的最后一列(lay)显示1863.我不想显示。你能告诉如何避免它。 – Rao 2013-03-06 11:28:47

+0

@PBLNarasimhaRao将'max(lay)'替换为'(CASE当镜头不是NULL,那么max(lay)ELSE''END)'。 – 2013-03-06 11:33:52

1

试试这个

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

,如果你想成为空只是''

+0

在7.75旁边的最后一行最后一列(放置)显示1863.我不想显示。你能告诉如何避免它。 – Rao 2013-03-06 11:29:05

+0

看看我编辑的答案可能会帮助你 – 2013-03-06 11:38:08

+0

,因为我认为它更好,如果你也计算总共有多少个字段。 – 2013-03-06 11:41:02

1

Here更换count(*)是建立在功能组的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; 
+0

在7.75旁边的最后一列最后一列(lay)显示1863.我不想显示。你能告诉如何避免它。 – Rao 2013-03-06 11:28:32

+0

尝试 SELECT 聚结(射击,“总计”)AS拍摄 ,总和(秒)二段 ,情况下,当拍摄不为空则分钟(铺设)否则“”末端躺在 FROM MY_TABLE 其中铺设=” 1863' group by shot with rollup; – 2013-03-06 11:34:54

1

在所有它看起来不正确使用“奠定”了TOTAL行列。除此之外,这里是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'; 
的情况下,

此外,如果列“射击”将是一个表中是唯一的例子中,将有可能使用一个查询:

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'; 
+0

不要忘记在代码中发布时使用“格式代码”按钮{} =) – Raad 2013-03-06 13:54:36