SQL 中从日期到日期按小时计算的每个元素的总和值
Sum values of each element by hour from date to date in SQL
我搜索了很多,但找不到答案。也许有人可以给我一些提示:
我有一个 table,其中包含以下列和数据(仅作为示例):
+-------+------------------+----+--------+--------+
| Type | InsertDate | ID | Value1 | Value2 |
+-------+------------------+----+--------+--------+
| Data | 2019-04-29 14:30 | 01 | 2 | 1 |
| Info | 2019-04-29 14:30 | 01 | 3 | 3 |
| Data | 2019-04-29 14:42 | 01 | 5 | 5 |
| Data | 2019-04-29 14:42 | 02 | 8 | 5 |
| Info | 2019-04-28 09:30 | 02 | 1 | 7 |
| Data | 2019-04-28 12:30 | 02 | 8 | 0 |
| Data | 2019-04-28 12:10 | 02 | 3 | 1 |
+-------+------------------+----+--------+--------+
现在我想要实现的是在配置的时间内为每个类型为数据的 ID 每小时求和 Value1。 IE。从 28.04 到 29.04 我想要这样的输出:
+----+------------------+------------------+
| ID | 12:00 28-04-2019 | 14:00 29-04-2019 |
+----+------------------+------------------+
| 01 | 0 | 7 |
| 02 | 11 | 8 |
+----+------------------+------------------+
我发现了很多如何对一个 ID 每小时求和 Value1 的例子,但我需要为多个 ID 输出。
我现在有以下查询:
DECLARE @cols NVARCHAR(20000)
SELECT
ID,
DATEADD(hour, DATEDIFF(hour, '00:00:00', InsertDate), '00:00:00') as TruncatedToHour,
sum(Value1) as data
INTO t3
FROM table1
WHERE Type = 'Data' AND InsertDate > '2019-04-28 00:00'
GROUP BY
ID,
DATEADD(hour, DATEDIFF(hour, '00:00:00', InsertDate), '00:00:00')
SELECT @cols = LIST(DISTINCT cast(TruncatedToHour as nvarchar(1000)), ', ') FROM t3
此查询 returns 所有需要的数据(但格式不正确)并且正在为所需的 table 结构动态创建列名 (@cols)。
现在我需要创建所需的 table 结构并用适当的数据填充它。有人可以帮忙吗?
好的,我找到了适合我的解决方案。我绝对不是 Sybase 专家,但我想与社区分享这个解决方案。也许这会帮助某人或某些专家会更好地改进它。
我的解决方案(我添加了注释来解释代码的作用):
DECLARE @delimiter char(1), @quotechar char(1), @pattern varchar(500), @piece varchar(500), @pos int, @datefrom TEXT
DECLARE @cols TEXT
DECLARE @query TEXT
SET @datefrom = '2019-04-26 00:00' --//---> Define the 'date from' here
SET @quotechar = CHAR (39)
SET @delimiter = ','
--//Group everything by id and date and store it to temp table #t3
SELECT
ID,
DATEADD(minute, -DATEPART(minute, InsertDate), InsertDate) as TruncatedToHour,
sum(Value1) as data
INTO #t3
FROM table1
WHERE Type = 'Data' AND InsertDate >= @datefrom
GROUP BY
ID,
DATEADD(minute, -DATEPART(minute, InsertDate), InsertDate)
--//Select distinct the dates and hours from #t3 to create columns for the result table
--//and return them as delimited list
SELECT @cols = LIST(DISTINCT cast(TruncatedToHour as TEXT), ',') FROM #t3
--//Prepare the query which will create the result table
SET @pattern = '%' + @delimiter + '%'
SET @pos = patindex(@pattern , @cols)
SELECT @query = 'SELECT ID, max (case when TruncatedToHour = ' + @quotechar
--//Loop through all column names from @cols and add them to the query
WHILE @pos <> 0
BEGIN
SET @piece = LEFT(@cols, @pos - 1)
--// In @piece we have now a single column name
SELECT @query = @query + @piece + @quotechar + ' then data else null end) ' +@quotechar +@piece + @quotechar + ', max (case when TruncatedToHour = ' + @quotechar
SET @cols = stuff(@cols, 1, @pos, '')
SET @pos = patindex(@pattern , @cols)
END
SELECT @query = @query + ' INTO #t4 FROM #t3 GROUP BY ID ORDER BY ID'
SELECT @query = REPLACE(@query, ', max (case when TruncatedToHour = ' + @quotechar + ' ', ' ')
--//Execute the @query and collect the data from #t4
EXECUTE(@query)
SELECT * FROM #t4 ORDER BY ID
我搜索了很多,但找不到答案。也许有人可以给我一些提示: 我有一个 table,其中包含以下列和数据(仅作为示例):
+-------+------------------+----+--------+--------+
| Type | InsertDate | ID | Value1 | Value2 |
+-------+------------------+----+--------+--------+
| Data | 2019-04-29 14:30 | 01 | 2 | 1 |
| Info | 2019-04-29 14:30 | 01 | 3 | 3 |
| Data | 2019-04-29 14:42 | 01 | 5 | 5 |
| Data | 2019-04-29 14:42 | 02 | 8 | 5 |
| Info | 2019-04-28 09:30 | 02 | 1 | 7 |
| Data | 2019-04-28 12:30 | 02 | 8 | 0 |
| Data | 2019-04-28 12:10 | 02 | 3 | 1 |
+-------+------------------+----+--------+--------+
现在我想要实现的是在配置的时间内为每个类型为数据的 ID 每小时求和 Value1。 IE。从 28.04 到 29.04 我想要这样的输出:
+----+------------------+------------------+
| ID | 12:00 28-04-2019 | 14:00 29-04-2019 |
+----+------------------+------------------+
| 01 | 0 | 7 |
| 02 | 11 | 8 |
+----+------------------+------------------+
我发现了很多如何对一个 ID 每小时求和 Value1 的例子,但我需要为多个 ID 输出。
我现在有以下查询:
DECLARE @cols NVARCHAR(20000)
SELECT
ID,
DATEADD(hour, DATEDIFF(hour, '00:00:00', InsertDate), '00:00:00') as TruncatedToHour,
sum(Value1) as data
INTO t3
FROM table1
WHERE Type = 'Data' AND InsertDate > '2019-04-28 00:00'
GROUP BY
ID,
DATEADD(hour, DATEDIFF(hour, '00:00:00', InsertDate), '00:00:00')
SELECT @cols = LIST(DISTINCT cast(TruncatedToHour as nvarchar(1000)), ', ') FROM t3
此查询 returns 所有需要的数据(但格式不正确)并且正在为所需的 table 结构动态创建列名 (@cols)。 现在我需要创建所需的 table 结构并用适当的数据填充它。有人可以帮忙吗?
好的,我找到了适合我的解决方案。我绝对不是 Sybase 专家,但我想与社区分享这个解决方案。也许这会帮助某人或某些专家会更好地改进它。
我的解决方案(我添加了注释来解释代码的作用):
DECLARE @delimiter char(1), @quotechar char(1), @pattern varchar(500), @piece varchar(500), @pos int, @datefrom TEXT
DECLARE @cols TEXT
DECLARE @query TEXT
SET @datefrom = '2019-04-26 00:00' --//---> Define the 'date from' here
SET @quotechar = CHAR (39)
SET @delimiter = ','
--//Group everything by id and date and store it to temp table #t3
SELECT
ID,
DATEADD(minute, -DATEPART(minute, InsertDate), InsertDate) as TruncatedToHour,
sum(Value1) as data
INTO #t3
FROM table1
WHERE Type = 'Data' AND InsertDate >= @datefrom
GROUP BY
ID,
DATEADD(minute, -DATEPART(minute, InsertDate), InsertDate)
--//Select distinct the dates and hours from #t3 to create columns for the result table
--//and return them as delimited list
SELECT @cols = LIST(DISTINCT cast(TruncatedToHour as TEXT), ',') FROM #t3
--//Prepare the query which will create the result table
SET @pattern = '%' + @delimiter + '%'
SET @pos = patindex(@pattern , @cols)
SELECT @query = 'SELECT ID, max (case when TruncatedToHour = ' + @quotechar
--//Loop through all column names from @cols and add them to the query
WHILE @pos <> 0
BEGIN
SET @piece = LEFT(@cols, @pos - 1)
--// In @piece we have now a single column name
SELECT @query = @query + @piece + @quotechar + ' then data else null end) ' +@quotechar +@piece + @quotechar + ', max (case when TruncatedToHour = ' + @quotechar
SET @cols = stuff(@cols, 1, @pos, '')
SET @pos = patindex(@pattern , @cols)
END
SELECT @query = @query + ' INTO #t4 FROM #t3 GROUP BY ID ORDER BY ID'
SELECT @query = REPLACE(@query, ', max (case when TruncatedToHour = ' + @quotechar + ' ', ' ')
--//Execute the @query and collect the data from #t4
EXECUTE(@query)
SELECT * FROM #t4 ORDER BY ID