Sql server Transact-sql:删除表中的一个对应行

Sql server Transact-sql:删除表中的一个对应行,sql-server,tsql,Sql Server,Tsql,我们有一个类似的表格: 时间戳、计数、bunchOData 计数始终为1,除非有人出错并希望删除条目。删除在表中显示为新的、相同的行,计数为-1。因此: timestamp count bunchOData ------------------- ----- ---------- 2017-05-31 13:42:16 1 stuff 2017-05-31 13:42:27 -1 stuff 我必须将数据移动到一个新表中,在该表中删除的数据将被

我们有一个类似的表格: 时间戳、计数、bunchOData

计数始终为1,除非有人出错并希望删除条目。删除在表中显示为新的、相同的行,计数为-1。因此:

timestamp            count  bunchOData
-------------------  -----  ----------
2017-05-31 13:42:16  1      stuff
2017-05-31 13:42:27  -1     stuff
我必须将数据移动到一个新表中,在该表中删除的数据将被简单地删除。 因此,要迁移数据,我必须: 对于计数为-1的每块板,删除它和具有相同bunchOData且计数为1的最近(按时间)单板

我如何有效地做到这一点

编辑:为了让事情更清楚一些:

下面是表格中的示例:

DATE_TIME                   SPECIE_CODE LOAD                 LOAD_LIMIT           THICKNESS  GRADE_CODE                                         SURFACE_MEASURE                                    FBM                                                LOG_COUNT
--------------------------- ----------- -------------------- -------------------- ---------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -----------
2016-12-01 10:40:46         ASH         850-OHP              15000                4/4        Sel                                                13                                                 13                                                 1
2016-12-01 10:40:52         ASH         850-OHP              15000                4/4        Sel                                                -13                                                -13                                                -1
2016-12-01 10:48:32         ASH         850-OHP              15000                4/4        Sel                                                6                                                  6                                                  1
2016-12-01 10:48:43         ASH         850-BSI3             10000000             6/4        Stb                                                6                                                  9                                                  1
2016-12-01 10:48:51         ASH         850-BSI1             10000000             4/4        Sel S                                              5                                                  5                                                  1
2016-12-01 10:48:59         ASH         850-EMPIRE           500                  4/4        2&3Com                                             6                                                  6                                                  1
2016-12-01 10:49:47         ASH         850-BSI2             10000000             6/4        1Com                                               5                                                  7.5                                                1
2016-12-01 10:49:56         ASH         850-BSI3             10000000             6/4        Stb                                                5                                                  7.5                                                1
2016-12-01 10:50:03         ASH         850-BSI1             10000000             4/4        1Com                                               10                                                 10                                                 1
2016-12-01 10:50:20         ASH         850-EMPIRE           500                  4/4        2&3Com                                             10                                                 10                                                 1
2016-12-01 10:50:27         ASH         850-EMPIRE           500                  4/4        2&3Com                                             5                                                  5                                                  1
2016-12-01 10:50:36         ASH         850-BSI1             10000000             4/4        Sel S                                              6                                                  6                                                  1
2016-12-01 10:50:47         ASH         850-EMPIRE           500                  4/4        2&3Com                                             10                                                 10                                                 1
2016-12-01 10:52:10         ASH         850-BSI1             10000000             4/4        Frm                                                5                                                  5                                                  1
2016-12-01 10:52:21         ASH         850-BSI1             10000000             4/4        Frm                                                6                                                  6                                                  1
2016-12-01 10:52:26         ASH         850-BSI1             10000000             4/4        Frm                                                5                                                  5                                                  1
2016-12-01 10:52:39         ASH         850-BSI2             10000000             6/4        1Com                                               10                                                 15                                                 1
2016-12-01 10:52:48         ASH         850-BSI3             10000000             6/4        Stb                                                6                                                  9                                                  1
2016-12-01 10:52:54         ASH         850-BSI3             10000000             6/4        Stb                                                6                                                  9                                                  1
2016-12-01 10:53:00         ASH         850-BSI3             10000000             6/4        Stb                                                6                                                  9                                                  1
2016-12-01 10:53:06         ASH         850-OHP              15000                4/4        Sel                                                5                                                  5                                                  1
2016-12-01 10:55:31         ASH         850-BSI3             10000000             6/4        Stb                                                6                                                  9                                                  1
2016-12-01 10:59:30         ASH         850-BSI3             10000000             6/4        Stb                                                6                                                  9                                                  1
2016-12-01 10:59:37         ASH         850-OHP              15000                4/4        Sel                                                6                                                  6                                                  1
2016-12-01 10:59:48         ASH         850-BSI3             10000000             6/4        Stb                                                5                                                  7.5                                                1
2016-12-01 10:59:54         ASH         850-BSI2             10000000             6/4        1Com                                               10                                                 15                                                 1
2016-12-01 11:00:08         ASH         850-BSI2             10000000             6/4        1Com                                               -10                                                -15                                                -1
2016-12-01 11:00:20         ASH         850-BSI2             10000000             6/4        1Com                                               10                                                 15                                                 1
2016-12-01 11:01:02         ASH         850-BSI3             10000000             6/4        Stb                                                6                                                  9                                                  1
我想删除log_count中带有“-1”的条目,以及前面(但可能不立即在前面)带有log count中带有“1”的对应条目。像这样:

DATE_TIME                   SPECIE_CODE LOAD                 LOAD_LIMIT           THICKNESS  GRADE_CODE                                         SURFACE_MEASURE                                    FBM                                                LOG_COUNT
--------------------------- ----------- -------------------- -------------------- ---------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -----------
2016-12-01 10:48:32         ASH         850-OHP              15000                4/4        Sel                                                6                                                  6                                                  1
2016-12-01 10:48:43         ASH         850-BSI3             10000000             6/4        Stb                                                6                                                  9                                                  1
2016-12-01 10:48:51         ASH         850-BSI1             10000000             4/4        Sel S                                              5                                                  5                                                  1
2016-12-01 10:48:59         ASH         850-EMPIRE           500                  4/4        2&3Com                                             6                                                  6                                                  1
2016-12-01 10:49:47         ASH         850-BSI2             10000000             6/4        1Com                                               5                                                  7.5                                                1
2016-12-01 10:49:56         ASH         850-BSI3             10000000             6/4        Stb                                                5                                                  7.5                                                1
2016-12-01 10:50:03         ASH         850-BSI1             10000000             4/4        1Com                                               10                                                 10                                                 1
2016-12-01 10:50:20         ASH         850-EMPIRE           500                  4/4        2&3Com                                             10                                                 10                                                 1
2016-12-01 10:50:27         ASH         850-EMPIRE           500                  4/4        2&3Com                                             5                                                  5                                                  1
2016-12-01 10:50:36         ASH         850-BSI1             10000000             4/4        Sel S                                              6                                                  6                                                  1
2016-12-01 10:50:47         ASH         850-EMPIRE           500                  4/4        2&3Com                                             10                                                 10                                                 1
2016-12-01 10:52:10         ASH         850-BSI1             10000000             4/4        Frm                                                5                                                  5                                                  1
2016-12-01 10:52:21         ASH         850-BSI1             10000000             4/4        Frm                                                6                                                  6                                                  1
2016-12-01 10:52:26         ASH         850-BSI1             10000000             4/4        Frm                                                5                                                  5                                                  1
2016-12-01 10:52:39         ASH         850-BSI2             10000000             6/4        1Com                                               10                                                 15                                                 1
2016-12-01 10:52:48         ASH         850-BSI3             10000000             6/4        Stb                                                6                                                  9                                                  1
2016-12-01 10:52:54         ASH         850-BSI3             10000000             6/4        Stb                                                6                                                  9                                                  1
2016-12-01 10:53:00         ASH         850-BSI3             10000000             6/4        Stb                                                6                                                  9                                                  1
2016-12-01 10:53:06         ASH         850-OHP              15000                4/4        Sel                                                5                                                  5                                                  1
2016-12-01 10:55:31         ASH         850-BSI3             10000000             6/4        Stb                                                6                                                  9                                                  1
2016-12-01 10:59:30         ASH         850-BSI3             10000000             6/4        Stb                                                6                                                  9                                                  1
2016-12-01 10:59:37         ASH         850-OHP              15000                4/4        Sel                                                6                                                  6                                                  1
2016-12-01 10:59:48         ASH         850-BSI3             10000000             6/4        Stb                                                5                                                  7.5                                                1
2016-12-01 11:00:20         ASH         850-BSI2             10000000             6/4        1Com                                               10                                                 15                                                 1
2016-12-01 11:01:02         ASH         850-BSI3             10000000             6/4        Stb                                                6                                                  9                                                  1

这一切都是可行的,但如果您的源表中有一个唯一的键,那么就更容易了。这样的话,你就有了一个把手

我建议,因为这是数据迁移,可能是一次性的/有问题的任务,你可以考虑把它分解成步骤。我不会向您提供有效的SQL,因为我从您的问题中没有足够的信息来这样做,但我将这样开始:

  • 列出[count]=-1的情况,因为这些是您需要匹配和删除的所有取消
  • 理想情况下,这将是正在处理的表的唯一键列表,存储为临时(甚至永久)表
  • 从该列表中,您可以找到要删除的匹配记录,使用窗口函数(例如ROW_NUMBER())根据时间戳(最近的时间戳)选择最佳匹配,其中存在多个匹配
  • 有些取消可能没有匹配项,因此您可以将其放在一边并手动进行调查
  • 甚至可能存在重复匹配(完全相同的时间戳)的情况,您需要再次进行调查
  • 剩下的匹配现在基本上是两个列表,一个用于取消的唯一键列表,另一个用于被取消的行的相同大小的列表
  • 删除所有这些行,或以某种方式将它们标记为不迁移

如果你没有任何唯一的密钥,那么我甚至会考虑在临时的基础上创建一个键,因为这会使它变得更容易。您可以通过以下方式来实现:

SELECT NEWID() AS temp_key, * INTO [workingTable] FROM [myTable];
在该工作表上完成所有工作,然后从该工作表迁移数据,并在该过程中删除现在的冗余密钥


好的,现在我们有了数据,我可以告诉你这在现实生活中是如何工作的

第一项工作是将数据加载到临时表中,以便我可以使用它:

SET NOCOUNT ON;

--This is the source data
IF OBJECT_ID('tempdb..#source') IS NOT NULL
    DROP TABLE #source;
CREATE TABLE #source (
    DATE_TIME DATETIME,
    SPECIE_CODE VARCHAR(3),
    [LOAD] VARCHAR(25),
    LOAD_LIMIT INT,
    THICKNESS VARCHAR(4),
    GRADE_CODE VARCHAR(20),
    SURFACE_MEASURE INT,
    FBM INT,
    LOG_COUNT INT);
INSERT INTO #source SELECT '2016-12-01 10:40:46', 'ASH', '850-OHP', 15000, '4/4', 'Sel', 13, 13, 1;
INSERT INTO #source SELECT '2016-12-01 10:40:52', 'ASH', '850-OHP', 15000, '4/4', 'Sel', -13, -13, -1;
INSERT INTO #source SELECT '2016-12-01 10:48:32', 'ASH', '850-OHP', 15000, '4/4', 'Sel', 6, 6, 1;
INSERT INTO #source SELECT '2016-12-01 10:48:43', 'ASH', '850-BSI3', 10000000, '6/4', 'Stb', 6, 9, 1;
INSERT INTO #source SELECT '2016-12-01 10:48:51', 'ASH', '850-BSI1', 10000000, '4/4', 'Sel S', 5, 5, 1;
INSERT INTO #source SELECT '2016-12-01 10:48:59', 'ASH', '850-EMPIRE', 500, '4/4', '2&3Com', 6, 6, 1;
INSERT INTO #source SELECT '2016-12-01 10:49:47', 'ASH', '850-BSI2', 10000000, '6/4', '1Com', 5, 7.5, 1;
INSERT INTO #source SELECT '2016-12-01 10:49:56', 'ASH', '850-BSI3', 10000000, '6/4', 'Stb', 5, 7.5, 1;
INSERT INTO #source SELECT '2016-12-01 10:50:03', 'ASH', '850-BSI1', 10000000, '4/4', '1Com', 10, 10, 1
INSERT INTO #source SELECT '2016-12-01 10:50:20', 'ASH', '850-EMPIRE', 500, '4/4', '2&3Com', 10, 10, 1;
INSERT INTO #source SELECT '2016-12-01 10:50:27', 'ASH', '850-EMPIRE', 500, '4/4', '2&3Com', 5, 5, 1;
INSERT INTO #source SELECT '2016-12-01 10:50:36', 'ASH', '850-BSI1', 10000000, '4/4', 'Sel S', 6, 6, 1;
INSERT INTO #source SELECT '2016-12-01 10:50:47', 'ASH', '850-EMPIRE', 500, '4/4', '2&3Com', 10, 10, 1;
INSERT INTO #source SELECT '2016-12-01 10:52:10', 'ASH', '850-BSI1', 10000000, '4/4', 'Frm', 5, 5, 1;
INSERT INTO #source SELECT '2016-12-01 10:52:21', 'ASH', '850-BSI1', 10000000, '4/4', 'Frm', 6, 6, 1;
INSERT INTO #source SELECT '2016-12-01 10:52:26', 'ASH', '850-BSI1', 10000000, '4/4', 'Frm', 5, 5, 1;
INSERT INTO #source SELECT '2016-12-01 10:52:39', 'ASH', '850-BSI2', 10000000, '6/4', '1Com', 10, 15, 1;
INSERT INTO #source SELECT '2016-12-01 10:52:48', 'ASH', '850-BSI3', 10000000, '6/4', 'Stb', 6, 9, 1;
INSERT INTO #source SELECT '2016-12-01 10:52:54', 'ASH', '850-BSI3', 10000000, '6/4', 'Stb', 6, 9, 1;
INSERT INTO #source SELECT '2016-12-01 10:53:00', 'ASH', '850-BSI3', 10000000, '6/4', 'Stb', 6, 9, 1;
INSERT INTO #source SELECT '2016-12-01 10:53:06', 'ASH', '850-OHP', 15000, '4/4', 'Sel', 5, 5, 1;
INSERT INTO #source SELECT '2016-12-01 10:55:31', 'ASH', '850-BSI3', 10000000, '6/4', 'Stb', 6, 9, 1;
INSERT INTO #source SELECT '2016-12-01 10:59:30', 'ASH', '850-BSI3', 10000000, '6/4', 'Stb', 6, 9, 1;
INSERT INTO #source SELECT '2016-12-01 10:59:37', 'ASH', '850-OHP', 15000, '4/4', 'Sel', 6, 6, 1;
INSERT INTO #source SELECT '2016-12-01 10:59:48', 'ASH', '850-BSI3', 10000000, '6/4', 'Stb', 5, 7.5, 1;
INSERT INTO #source SELECT '2016-12-01 10:59:54', 'ASH', '850-BSI2', 10000000, '6/4', '1Com', 10, 15, 1;
INSERT INTO #source SELECT '2016-12-01 11:00:08', 'ASH', '850-BSI2', 10000000, '6/4', '1Com', -10, -15, -1;
INSERT INTO #source SELECT '2016-12-01 11:00:20', 'ASH', '850-BSI2', 10000000, '6/4', '1Com', 10, 15, 1;
INSERT INTO #source SELECT '2016-12-01 11:01:02', 'ASH', '850-BSI3', 10000000, '6/4', 'Stb', 6, 9, 1;
现在我有29行数据要处理。下一项工作是确定取消:

--Assuming that the timestamp is unique, make a list of cancelled items
IF OBJECT_ID('tempdb..#cancelled') IS NOT NULL
    DROP TABLE #cancelled;
SELECT *, CONVERT(DATETIME, NULL) AS MATCHED_DATE_TIME INTO #cancelled FROM #source WHERE LOG_COUNT = -1;
这将给我一个列表,其中包括两个要识别、匹配和删除的取消。我就是这样做的:

--Attempt to find matches
WITH BestMatch AS (
    SELECT
        c.*,
        s.DATE_TIME AS CANDIDATE_MATCHED_DATE_TIME,
        ROW_NUMBER() OVER (PARTITION BY c.DATE_TIME ORDER BY s.DATE_TIME DESC) AS MATCH_ID
    FROM
        #cancelled c
        INNER JOIN #source s ON s.DATE_TIME <= c.DATE_TIME AND s.SPECIE_CODE = c.SPECIE_CODE AND s.[LOAD] = c.[LOAD] AND s.LOAD_LIMIT = c.LOAD_LIMIT
            AND s.THICKNESS = c.THICKNESS AND s.GRADE_CODE = c.GRADE_CODE AND s.SURFACE_MEASURE = c.SURFACE_MEASURE * -1 AND s.FBM = c.FBM * -1)
UPDATE
    c
SET
    MATCHED_DATE_TIME = bm.CANDIDATE_MATCHED_DATE_TIME
FROM
    BestMatch bm
    INNER JOIN #cancelled c ON c.DATE_TIME = bm.DATE_TIME
WHERE
    bm.MATCH_ID = 1; --Only pick the latest match
第一个取消是针对负载值为850-OHP的行,这里只有一个候选行,因此没有问题。第二个取消是针对负载值为850-BS12的行,这一次有两个潜在匹配。我们对它们进行排序,并为每一个分配一个匹配ID,该ID将从1开始,并为每个后续匹配递增1。MATCH_ID是按日期时间顺序排列的,因此MATCH_ID为1(10:59:54)的行是我们要删除的行,MATCH_ID为2(10:52:39)的行将保持不变

此时,您可能应该检查是否存在任何问题:

--Investigate any issues
SELECT * FROM #cancelled WHERE MATCHED_DATE_TIME IS NULL;
但是没有,所以我们继续执行删除:

--Perform the delete
DELETE FROM #source WHERE LOG_COUNT = -1;
DELETE s FROM #source s INNER JOIN #cancelled c ON c.MATCHED_DATE_TIME = s.DATE_TIME;
完成后,还剩下25行:

--Show the results
SELECT * FROM #source;

首先,获取表中出现的所有种类代码、载荷、载荷极限和厚度值的列表,其中count=-1。这些是所有拆除的规格代码、荷载、荷载极限和厚度值。然后删除所有具有此类值的行。无论它们的计数值是多少,它都将删除所有这些:

delete from MyTable 
Where SPECIE_CODE + LOAD + LOAD_LIMIT + THICKNESS + GRADE_CODE 
     in (select SPECIE_CODE + LOAD + LOAD_LIMIT + THICKNESS + GRADE_CODE from @MyTable where counts = -1)

这里没有足够的信息来提供一个非常可靠的答案。这是一个很好的起点。出于兴趣,你为什么让它这样工作?似乎有可能出错。你的问题有些令人困惑。一方面,你说你想删除的只是删除,但后来你补充说,他们必须有关闭日期以及。这个结束日期的条件有必要吗?@Leonidas:我唯一能给你的答案就是“遗产”这个神奇的词。删除删除很容易,但我还想删除'-1'记录要撤消的原始条目。谢谢,Richard。困难来自你的第三个要点。我在我的帖子的编辑中添加了一些真实的数据,可以更好地说明我的问题。我只想删除一个匹配的条目,而不是全部。
delete from MyTable 
Where SPECIE_CODE + LOAD + LOAD_LIMIT + THICKNESS + GRADE_CODE 
     in (select SPECIE_CODE + LOAD + LOAD_LIMIT + THICKNESS + GRADE_CODE from @MyTable where counts = -1)