如何将SQL Server表中的行拆分为多个表

时间:2017-08-03 09:20:09

标签: sql-server

我有一张超过1000条记录的表格。以下是表中的示例摘录:

VersionTested       RunDate          TestName       AverageTime
---------------------------------------------------------------
v.1                20170802-1036     function1        10.02
v.1                20170802-1036     function2        12.36
v.1                20170802-1036     function3        11.36
v.1                20170802-1036     function4        14.36
v.2                20170803-1000     function1        10.06
v.2                20170803-1000     function2        12.36
v.2                20170803-1000     function3        12.00
v.2                20170803-1000     function4        11.02
v.3                20170731-1000     function1        10.02
v.3                20170731-1000     function2        12.36
v.3                20170731-1000     function3        11.02
v.3                20170731-1000     function4        12.56

基本上我有106个函数正在针对不同的versionTested运行。所以我想要做的是比较每个函数与versionTested的平均时间。

请查看我正在寻找的输出:

Function1表:

VersionTested    RunDate        TestName    AverageTime
---------------------------------------------------------
 v.1             20170802-1036  function1    10.02
 v.2             20170803-1000  function1    10.06
 v.3             20170731-1000  function1    10.02

功能2表:

 VersionTested    RunDate        TestName    AverageTime
 -------------------------------------------------------
     v.1          20170802-1036  function2    12.36
     v.2          20170803-1000  function2    12.36
     v.3          20170731-1000  function2    12.36

我希望这种情况适用于所有106个功能。如何在T-SQL中实现这一目标?

最后一件事是根据不同的VersionTested绘制每个函数的图形来比较平均时间。

如何在T-SQL中实现?可能没有必要将这些信息分成多个表格?欢迎提出任何建议。

以下是我正忙着处理的代码,但我似乎无处可去:

SELECT 'RunDate' AS DateTested, 
        v.1, v.2, v.3
        FROM
        (SELECT *
         FROM TableName) AS SourceTable
        PIVOT
        (
         SUM(VersionTested)
         FOR VersionTested IN (v.1, v.2, v.3)
        ) AS PivotTable;

2 个答案:

答案 0 :(得分:0)

我不完全确定你想看到什么作为结果集。在问这样的问题时,不仅要显示样本数据,还要显示样本输出,这总是很好。我将样本数据加倍,以便AVG有工作要做(所以我们知道它正在工作!)。

因为我不确定枢轴应该是多少,所以我给出了两个版本:

declare @versiontests table
(
versiontested char(3),
datetested datetime,
functionname varchar(15),
timetaken float
)
INSERT INTO @versiontests VALUES('v.1','2017-08-02 10:36','function1',10.02)
INSERT INTO @versiontests VALUES('v.1','2017-08-02 10:36','function2',12.36)
INSERT INTO @versiontests VALUES('v.1','2017-08-02 10:36','function3',11.36)
INSERT INTO @versiontests VALUES('v.1','2017-08-02 10:36','function4',14.36)
INSERT INTO @versiontests VALUES('v.2','2017-08-03 10:00','function1',10.06)
INSERT INTO @versiontests VALUES('v.2','2017-08-03 10:00','function2',12.36)
INSERT INTO @versiontests VALUES('v.2','2017-08-03 10:00','function3',12.00)
INSERT INTO @versiontests VALUES('v.2','2017-08-03 10:00','function4',11.02)
INSERT INTO @versiontests VALUES('v.3','2017-07-31 10:00','function1',10.02)
INSERT INTO @versiontests VALUES('v.3','2017-07-31 10:00','function2',12.36)
INSERT INTO @versiontests VALUES('v.3','2017-07-31 10:00','function3',11.02)
INSERT INTO @versiontests VALUES('v.3','2017-07-31 10:00','function4',12.56)
INSERT INTO @versiontests VALUES('v.1','2017-08-02 11:36','function1',10.22)
INSERT INTO @versiontests VALUES('v.1','2017-08-02 11:36','function2',12.31)
INSERT INTO @versiontests VALUES('v.1','2017-08-02 11:36','function3',11.26)
INSERT INTO @versiontests VALUES('v.1','2017-08-02 11:36','function4',14.16)
INSERT INTO @versiontests VALUES('v.2','2017-08-03 11:00','function1',10.56)
INSERT INTO @versiontests VALUES('v.2','2017-08-03 11:00','function2',12.56)
INSERT INTO @versiontests VALUES('v.2','2017-08-03 11:00','function3',12.40)
INSERT INTO @versiontests VALUES('v.2','2017-08-03 11:00','function4',11.22)
INSERT INTO @versiontests VALUES('v.3','2017-07-31 11:00','function1',10.52)
INSERT INTO @versiontests VALUES('v.3','2017-07-31 11:00','function2',12.46)
INSERT INTO @versiontests VALUES('v.3','2017-07-31 11:00','function3',11.09)
INSERT INTO @versiontests VALUES('v.3','2017-07-31 11:00','function4',12.37)

SELECT functionname, datetested, [v.1], [v.2], [v.3]
        FROM
        (SELECT CAST(datetested AS date) as datetested, versiontested, functionname, timetaken
         FROM @versiontests) AS SourceTable
        PIVOT
        (
         AVG(timetaken) FOR versiontested in ([v.1], [v.2], [v.3])
        ) AS PivotTable
        ;
SELECT functionname, [v.1], [v.2], [v.3]
        FROM
        (SELECT versiontested, functionname, timetaken
         FROM @versiontests) AS SourceTable
        PIVOT
        (
         AVG(timetaken) FOR versiontested in ([v.1], [v.2], [v.3])
        ) AS PivotTable
        ;

修改

使用与上面相同的表声明和插入,但使用以下内容代替PIVOT SELECTS:

declare @functionNames table
(
functionname varchar(15),
rownum int
)

INSERT INTO @functionNames 
SELECT d.functionname, ROW_NUMBER() OVER (ORDER BY d.functionname) from 
(SELECT DISTINCT functionname FROM @versiontests) as d

declare @cnt int = (SELECT COUNT(*) FROM @functionNames)
declare @rowPtr int = 0
declare @tempFunc varchar(15)


while @rowPtr < @cnt
    begin
        SET @rowPtr = @rowPtr + 1
        SET @tempFunc = (SELECT functionname FROM @functionNames WHERE rownum = @rowPtr)        
        SELECT versiontested, datetested, functionname, timetaken FROM @versiontests
            WHERE functionname = @tempFunc
    end

这会将SELECT分成n个单独的SELECTS。如果您使用的是DataSet(例如来自c#),您将在DataSet中获得n个不同的DataTable。

我认为,虽然您希望按日期添加一些分组以获得每天的平均值,但我留给您了解。

答案 1 :(得分:0)

1这应该做你要求的......

USE tempdb;
GO

IF OBJECT_ID('tempdb.dbo.FunctionTestAll', 'U') IS NOT NULL 
DROP TABLE dbo.FunctionTestAll;

CREATE TABLE dbo.FunctionTestAll (
    VersionTested CHAR(3) NOT NULL,
    RunDate CHAR(13) NOT NULL,
    TestName CHAR(9) NOT NULL,
    AverageTime DECIMAL(5,2)
    );
INSERT dbo.FunctionTestAll (VersionTested, RunDate, TestName, AverageTime) VALUES
    ('v.1', '20170802-1036', 'function1', 10.02),
    ('v.1', '20170802-1036', 'function2', 12.36),
    ('v.1', '20170802-1036', 'function3', 11.36),
    ('v.1', '20170802-1036', 'function4', 14.36),
    ('v.2', '20170803-1000', 'function1', 10.06),
    ('v.2', '20170803-1000', 'function2', 12.36),
    ('v.2', '20170803-1000', 'function3', 12.00),
    ('v.2', '20170803-1000', 'function4', 11.02),
    ('v.3', '20170731-1000', 'function1', 10.02),
    ('v.3', '20170731-1000', 'function2', 12.36),
    ('v.3', '20170731-1000', 'function3', 11.02),
    ('v.3', '20170731-1000', 'function4', 12.56);
GO

--SELECT * FROM dbo.FunctionTestAll fta

--=========================================================

IF OBJECT_ID('tempdb.dbo.TablesToCreate', 'U') IS NOT NULL 
DROP TABLE dbo.TablesToCreate;

SELECT 
    TestID = ROW_NUMBER() OVER (ORDER BY (SELECT NULL)),
    fta.TestName
    INTO dbo.TablesToCreate
FROM
    dbo.FunctionTestAll fta
GROUP BY
    fta.TestName;

----------------------------------------------------------

DECLARE @TestID INT = 0;

WHILE EXISTS (SELECT 1 FROM dbo.TablesToCreate ttc WHERE ttc.TestID > @TestID)
BEGIN 
    SET @TestID = @TestID + 1;

    DECLARE @CreateTableSQL VARCHAR(1000) = '';

    SELECT 
        @CreateTableSQL = CONCAT('
CREATE TABLE dbo.', ttc.TestName, ' (
    VersionTested CHAR(3) NOT NULL,
    RunDate CHAR(13) NOT NULL,
    TestName CHAR(9) NOT NULL,
    AverageTime DECIMAL(5,2)
    );

INSERT dbo.', ttc.TestName, ' (VersionTested, RunDate, TestName, AverageTime)
SELECT 
    fta.VersionTested, fta.RunDate, fta.TestName, fta.AverageTime
FROM
    dbo.FunctionTestAll fta
WHERE
    fta.TestName = ''', ttc.TestName, ''';'
        )
    FROM
        dbo.TablesToCreate ttc
    WHERE
        ttc.TestID = @TestID;

    EXEC(@CreateTableSQL);
END;
GO


--  SELECT * FROM dbo.function1;
--  SELECT * FROM dbo.function2;
--  SELECT * FROM dbo.function3;
--  SELECT * FROM dbo.function4;

--  DROP TABLE dbo.function1;
--  DROP TABLE dbo.function2;
--  DROP TABLE dbo.function3;
--  DROP TABLE dbo.function4;
HTH,Jason