SQL Server 2005 - 如何对结果集中同一列中的2个结果进行滚动计算?

时间:2017-07-17 10:06:00

标签: sql sql-server-2005

例如,我有一个包含以下列的表:

EXTRACT_DATE, TABLE_NAME, NUMBER_ROWS, DATA_SIZE. 

DATA_SIZE列是bigint数据类型,我希望从另一个值中减去一个值,以便在单独的列中获取大小差异。结果集的最大行数为52行,必须对每组两行进行此操作。

有人可以帮助我使用我应该使用的代码吗?如果您需要更多信息,请与我们联系。

示例数据:

EXTRACT_DATE    TABLE_NAME  NUMBER_ROWS DATA_SIZE
2014-07-17      FGDISD      1           24576
2014-07-17      FFIDXH      1           24576
2014-07-17      FFIIRH      37          28672

每张桌子都有多个摘录,每个摘录一周都会回来。

预期输出

EXTRACT_DATE    TABLE_NAME  NUMBER_ROWS DATA_SIZE   SIZE_DIFF   
2017-07-15      FGLEDG      141673883   76221730816 184553472   
2017-07-08      FGLEDG      141323505   76037177344 184549376
2017-07-01      FGLEDG      140971673   75852627968 184549376

2 个答案:

答案 0 :(得分:0)

假设EXTRACT_DATE是唯一的,并且它是您用来订购结果集的列,您可以执行以下操作:

SELECT  EXTRACT_DATE, 
        TABLE_NAME, 
        NUMBER_ROWS, 
        DATA_SIZE,
        DATA_SIZE - 
        ISNULL((
            SELECT TOP 1 DATA_SIZE
            FROM TableName as t1
            WHERE t1.TABLE_NAME = t0.TABLE_NAME
            AND t1.EXTRACT_DATE < t0.EXTRACT_DATE
            ORDER BY EXTRACT_DATE DESC
        ), 0) As DATA_SIZE_DIFF
FROM TableName as t0

如果您提供样本数据作为DDL + DML以及期望的结果,我将能够测试我的答案。

答案 1 :(得分:0)

我已经能够使用两个临时表来解决我的问题,并使用每个临时表中的值来计算大小差异。我不会说这是做到这一点的最佳方式,但它似乎适用于我想要做的事情。如果有更简单的方法,我仍然希望看到它。

ALTER PROCEDURE [dbo].[TableGrowthReport]
@NoOWeeks int,
@TableName varchar(15)

AS
--Declares & sets variables
DECLARE @CurrentDate DATETIME
DECLARE @CalcDate DATETIME

SET @CurrentDate = DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()))
SET @CalcDate = DATEADD(ww, @NoOWeeks, @CurrentDate)

CREATE TABLE #Data 
(
    RowNo int,
    EXTRACT_DATE varchar(19),
    TABLE_NAME varchar(128),
    NUMBER_ROWS bigint,
    DATA_SIZE bigint,
    DATA_SIZE2 bigint,
);

CREATE TABLE #Data2 
(
    RowNo int,
    DATA_SIZE2 bigint
);

INSERT INTO #Data 
    (RowNo,
    EXTRACT_DATE,
    TABLE_NAME,
    NUMBER_ROWS,
    DATA_SIZE,
    DATA_SIZE2)
    SELECT
         ROW_NUMBER() OVER (ORDER BY EXTRACT_DATE desc) as RowNo,
         EXTRACT_DATE,
         TABLE_NAME,
         NUMBER_ROWS,
         DATA_SIZE,
         NULL
    FROM M3Rows_PF
    WHERE TABLE_NAME = @TableName
        AND EXTRACT_DATE > 
            (SELECT CONVERT(varchar(10), @CalcDate, 20));

INSERT INTO #Data2 
    (RowNo,
    DATA_SIZE2)
        SELECT 
            RowNo,
            DATA_SIZE
        FROM
            (
                SELECT
                ROW_NUMBER() OVER (ORDER BY EXTRACT_DATE desc) - 1 as RowNo,
                EXTRACT_DATE,
                TABLE_NAME,
                NUMBER_ROWS,
                DATA_SIZE
                FROM M3Rows_PF
                WHERE TABLE_NAME = @TableName 
                    AND EXTRACT_DATE > 
                        (SELECT CONVERT(varchar(10), @CalcDate, 20))
                        )r
                        WHERE rowno > 0;

UPDATE a 
SET DATA_SIZE2 = b.DATA_SIZE2
FROM #Data a
JOIN #Data2 b ON a.RowNo = b.RowNo
WHERE a.RowNo = b.RowNo

SELECT  
    RowNo,
    EXTRACT_DATE,
    TABLE_NAME,
    NUMBER_ROWS,
    DATA_SIZE,
    DATA_SIZE2,
    CASE 
        WHEN DATA_SIZE > 0 AND DATA_SIZE < 10000000
            THEN LEFT(DATA_SIZE * 1.0 / 10000, 4) + 'kb' 
        WHEN DATA_SIZE >= 10000000 AND DATA_SIZE < 1000000000
            THEN LEFT(DATA_SIZE * 1.0 / 1000000, 5)  + 'mb'
        ELSE 
            LEFT(DATA_SIZE * 1.0 / 1000000000, 5) + 'gb' END AS DATA_SIZECONV,
    DATA_SIZE - DATA_SIZE2 AS SIZE_DIFF,
    LEFT((DATA_SIZE - DATA_SIZE2) * 1.0 / 1000000, 5) AS SIZE_DIFFmb
FROM #data
WHERE TABLE_NAME = @TableName 
    AND EXTRACT_DATE > 
        (SELECT 
            CONVERT(varchar(10), @CalcDate, 20)
        )   

DROP TABLE #Data
DROP TABLE #Data2