【问题标题】:Sort several datasets to one dataset将多个数据集排序为一个数据集
【发布时间】:2012-02-26 04:48:37
【问题描述】:

几天前我问过同样的问题,但我想用一个单独的 C# 程序来解决我的问题。现在我想直接用 SQL 来做。

That's my problem (很抱歉把你链接到另一个问题)

我的第一次尝试是创建这个触发器:

CREATE TRIGGER myNewTrigger ON [dbo].[myTable]
FOR INSERT
AS

INSERT INTO dbo.myTargetTable
        (TIMESTAMP, VALUE_1, VALUE_2, VALUE_3, VALUE_4)
    SELECT
        DATEADD(SECOND, TIMESTAMP_S,'19700101'), VALUE, VALUE, VALUE, VALUE
        FROM inserted

GO

这将创建四行,每行具有相同的四个值。但是如何将每一行的值放在具有不同列的一行中呢?

感谢您的帮助!

【问题讨论】:

  • 所以inserted 有一个值,MyTargetTable 有四个,你在触发器中捕获它???? TimeStamp_S 是否保证所有“四个插入”的值都相同?这些插入总是以相同的顺序,还是顺序无关?
  • 我认为“插入”没有多行。 myTargetTable 应该只有一个数据集!是的,所有四个值的时间戳始终相同。顺序始终相同。 ...四个值以相同的时间戳出现在四个不同的行中,但我希望它们与这个时间戳在一行中。

标签: sql sql-server-2008 sorting


【解决方案1】:

如果触发器没有问题,这个未经测试的 Select-Statement 可能是您的解决方案。

第一个问题:

每次插入 mytable 后都会触发触发器。 在第一次插入时间戳之后,只有一个值。所以你需要在第三或第四条记录之后更新。 您为最后一个而不是当前时间戳进行插入。我的解决方案没有解决这个问题。

第二个问题:

您需要确保只插入一次,而不是在每一行之后插入。 您可以在插入的 select 语句中添加 NOT IN 子句。 我的解决方案没有解决这个问题。

SELECT 
DISTINCT
TS
,(SELECT VALUE FROM
    (SELECT MT.TS, MT.VALUE ,ROW_NUMBER () OVER (ORDER BY TS, VALUE) AS ROWNUMBER
    FROM myTable MT
    WHERE MT.TS = TS) DATASET
    WHERE DATASET.ROWNUMBER = 1) AS VALUE1
,(SELECT VALUE FROM
    (SELECT TS, VALUE ,ROW_NUMBER () OVER (ORDER BY TS, VALUE) AS ROWNUMBER
    FROM myTable
    WHERE MT.TS = TS) DATASET
    WHERE DATASET.ROWNUMBER = 2) AS VALUE2
,(SELECT VALUE FROM
    (SELECT TS, VALUE ,ROW_NUMBER () OVER (ORDER BY TS, VALUE) AS ROWNUMBER
    FROM myTable
    WHERE MT.TS = TS) DATASET
    WHERE DATASET.ROWNUMBER = 3) AS VALUE3
,(SELECT VALUE FROM
    (SELECT TS, VALUE ,ROW_NUMBER () OVER (ORDER BY TS, VALUE) AS ROWNUMBER
    FROM myTable
    WHERE MT.TS = TS) DATASET
    WHERE DATASET.ROWNUMBER = 4) AS VALUE4
FROM inserted
GROUP BY TS 

您的问题的可能解决方案,在评论中说明:

使用这个未经测试的查询,您将最后一个而不是当前的 TS 插入到目标表中。这样,您就可以在写入 TS 的最后一个条目时进行更新,这样您就可以在插入它们之前写入所有值(1..4)。

它可能很慢:-)。但我不知道更好的方法。

SELECT 
 DISTINCT TOP 1
 TS
 ,(SELECT VALUE FROM
    (SELECT MT.TS, MT.VALUE ,ROW_NUMBER () OVER (ORDER BY TS, VALUE) AS ROWNUMBER
    FROM myTable MT
    WHERE MT.TS = TS) DATASET
    WHERE DATASET.ROWNUMBER = 1) AS VALUE1
,(SELECT VALUE FROM
    (SELECT TS, VALUE ,ROW_NUMBER () OVER (ORDER BY TS, VALUE) AS ROWNUMBER
    FROM myTable
    WHERE MT.TS = TS) DATASET
    WHERE DATASET.ROWNUMBER = 2) AS VALUE2
,(SELECT VALUE FROM
    (SELECT TS, VALUE ,ROW_NUMBER () OVER (ORDER BY TS, VALUE) AS ROWNUMBER
    FROM myTable
    WHERE MT.TS = TS) DATASET
    WHERE DATASET.ROWNUMBER = 3) AS VALUE3
,(SELECT VALUE FROM
    (SELECT TS, VALUE ,ROW_NUMBER () OVER (ORDER BY TS, VALUE) AS ROWNUMBER
    FROM myTable
    WHERE MT.TS = TS) DATASET
    WHERE DATASET.ROWNUMBER = 4) AS VALUE4
 FROM myTable
 WHERE TS < (SELECT MIN(TS) FROM INSERTED)
 AND TS NOT IN (SELECT TS FROM MyTargetTable)
 GROUP BY TS 

【讨论】:

  • 感谢您的帮助! SELECT DISTINCTGROUP BY 可以完成这项工作。但是,是的,问题在于inserted 可能只包含一个数据集,而不是全部四个数据集。我不知道如何检查这个..
  • @Blubb 我试图给你解决方案。在我更新的帖子中。我希望它有效。
  • 非常感谢!基本上你的解决方案成功了。我删除了倒数第二行(AND TS NOT...)并在最后添加了DELETE FROM myTargetTable WHERE VALUE_1 IS NULL OR VALUE_2 IS NULL OR VALUE_3 IS NULL OR VALUE_4 IS NULL。非常感谢您的帮助!!!
【解决方案2】:

有人可以让这对你来说更容易...... 凌乱而脆弱

基本上你需要

查看您是否在 myTargetTable fdor 中已有记录或时间戳。 如果不插入一个设置值1。 如果你这样做了,那么你需要测试一个空闲槽(值 2 到 4)并更新。

如果您插入了一个 ValueNumber,您可以做一些更强大的事情。

就我个人而言,我很想对此进行规范化,并将 MyTargetTable 设置为 TimeStamp、ValueNumber、Value,但如果您总是获得所有四个值,这会使您的存储需求增加三个时间戳和四个整数。我只能说,每当我看到一个包含 Column1 到 ColumnN 的表格时,就有人需要对其进行规范化。 :(

【讨论】:

    猜你喜欢
    • 2011-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-03
    • 1970-01-01
    相关资源
    最近更新 更多