简体   繁体   English

如何在 SQL Server 中对 1:15 这种类型的值求和

[英]How to sum 1:15 this type of values in SQL server

How to sum 1:15 this type of values in SQL server如何在 SQL Server 中对 1:15 这种类型的值求和

I try this query:我试试这个查询:

select sum((SELECT REPLACE(
           CONVERT(VARCHAR(8), TotalTime, 108),
           ':',
           '.'
          ) where Associate='4587')
          )
from Tracking
where Associate='4587'

error showing:错误显示:

Msg 130, Level 15, State 1, Line 45 Cannot perform an aggregate function on an expression containing an aggregate or a subquery.消息 130,级别 15,状态 1,第 45 行无法对包含聚合或子查询的表达式执行聚合函数。

You can try this using conditional aggregation您可以尝试使用条件聚合

select sum(case when Associate='2614' then REPLACE(CONVERT(VARCHAR(8), TotalTime, 108), ':', '.' ) end) 
from Tracking where Associate='4587'

Well, you have chosen the wrong data type to store this value, and this can lead to to a lot of problems, starting with ill-formatted values (What's stopping you from having a value like '1:86' , or even worst - 'dyjst' in that column?), through having to perform needlessly complicated queries to get some of the results (just like this one), ambiguous values such as 13:2 - Is that 20 minutes or just 2?, and there are a bunch of other problems I didn't write because I think you should get the picture by now.好吧,你选择了错误的数据类型来存储这个值,这可能会导致很多问题,从格式错误的值开始(是什么阻止你拥有像'1:86'这样的值,甚至最糟糕的 - 'dyjst'在该列中?),通过执​​行不必要的复杂查询来获得一些结果(就像这个),不明确的值,例如13:2 - 那是 20 分钟还是 2 分钟?,并且有一个一堆我没有写的其他问题,因为我认为你现在应该得到图片。

Surly the best way to solve this issue is to change the way you store the data.当然,解决这个问题的最好方法是改变你存储数据的方式。 If this data represents an hour in a day, you should be using the Time data type.如果此数据代表一天中的一个小时,则您应该使用Time数据类型。 If it stores a duration that might be larger than 24 hours, you might want to simply calculate the number of minutes and store that in an int.如果它存储的持续时间可能大于 24 小时,您可能只想计算分钟数并将其存储在一个 int 中。

However, assuming that for some reason (and yes, some of them might be valid reasons) you can't change the way you store this data - you will need to write a query that will translate this data for you to the number of minutes it represents (This would also be the case if you where to store it in the Time data type - you can't do SUM on Time values), and then sum that value.但是,假设出于某种原因(是的,其中一些可能是正当理由),您无法更改存储此数据的方式 - 您将需要编写一个查询,将这些数据转换为分钟数它代表(如果您将它存储在Time数据类型中的位置,情况也是如此 - 您不能对Time值执行SUM ),然后对该值求和。 If you want to display it back as the same format ( [h]h:mm ), you will need to translate the value from the sum back to this format.如果要将其显示为相同的格式 ( [h]h:mm ),则需要将值从sum回此格式。

I've put together a small demo that will show you one way to translate a string formatted as hh:mm to number of minutes and back - Once you get the number of minutes as an int, using sum is easy.我已经整理了一个小演示,它将向您展示一种将格式为hh:mm的字符串转换为分钟数并返回的方法 - 一旦您将分钟数作为整数,使用sum就很容易了。 Note : I didn't add any validation for the content of the strings!注意:我没有为字符串的内容添加任何验证!

So first, create and populate sample table ( Please , save us this step in your future questions):因此,首先,创建并填充示例表(在您以后的问题中保存我们这一步):

DECLARE @Tracking AS TABLE
(
    TotalTime varchar(10),
    Associate varchar(10)
);
INSERT INTO @Tracking (TotalTime, Associate) VALUES
('1:15', '4587'),
('1:05', '4588'),
('22:33', '4589'),
('73:50', '4590'),
('120:85', '4591'); -- Note: this will translate back as 121:25

Then, create a common table expression to translate the value in the TotalTime column to the number of minutes it represents:然后,创建一个公用表表达式,将 TotalTime 列中的值转换为其代表的分钟数:

;WITH CTE AS
(
    SELECT  Associate, 
            TotalTime As TotalTime,
            CAST(LEFT(TotalTime, CHARINDEX(':', TotalTime) - 1) AS Int) * 60 +
            CAST(RIGHT(TotalTime, LEN(TotalTime) - CHARINDEX(':', TotalTime)) As int)
            As NumberOfMinutes
    FROM @Tracking
)

And a select statement to translate it back to a time string:还有一个选择语句将其转换回时间字符串:

SELECT  Associate, TotalTime, NumberOfMinutes,
        CAST((NumberOfMinutes - (NumberOfMinutes % 60)) / 60 As varchar(3)) + ':' +
        RIGHT('00' + CAST(NumberOfMinutes % 60 As varchar(2)), 2) As TimeString
FROM CTE

Results:结果:

Associate   TotalTime   NumberOfMinutes     TimeString
4587        1:15        75                  1:15
4588        1:05        65                  1:05
4589        22:33       1353                22:33
4590        73:50       4430                73:50
4591        120:85      7285                121:25

This is an example of how you can sum a time column.这是如何对时间列求和的示例。 It returns a Days, Time and a datetime.它返回天数、时间和日期时间。 Time will be relevant as long as the sum is less than 24 hours otherwise it should be combined with Days.只要总和小于 24 小时,时间就具有相关性,否则应与天数相结合。 The datetime will include the day part as days after 1900-01-01.日期时间将包括 1900-01-01 之后的天数部分。

The query require valid data with data format hh:mi or h:mi:查询需要数据格式为 hh:mi 或 h:mi 的有效数据:

DECLARE @ table(col int, TotalTime time)

INSERT @ values(1,'1:15'),(1,'0:30'),(1,'0:05'),(1,'23:30'),(2,'1:15'),(2,'1:30')
SELECT
  col,
  datediff(d, 0, cast(sum(cast(cast(totaltime as datetime) as float)) as datetime)) Days,
  cast(cast(sum(cast(cast(totaltime as datetime) as float)) as datetime) as time(0)) Time,
  cast(sum(cast(cast(totaltime as datetime) as float)) as smalldatetime) DT
FROM 
  @
GROUP BY col

Result:结果:

col Days  Time     DT
1   1     01:20:00 1900-01-02 01:20:00
2   0     02:45:00 1900-01-01 02:45:00

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM