Transact sql:删除表

时间:2017-05-31 15:24:07

标签: sql-server tsql

我们有一个类似于这样的表: timestamp,count,bunchOData

计数总是1除非有人犯了错误并想要删除条目。删除在表中显示为count = -1的新的相同行。所以:

timestamp            count  bunchOData
-------------------  -----  ----------
2017-05-31 13:42:16  1      stuff
2017-05-31 13:42:27  -1     stuff

我必须将数据移动到一个新表中,只删除删除。 因此,要迁移数据,我必须: 对于count = -1的每个板,删除它和单个最近(按时间)的板具有相同的bunchOData,并且count = 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

我想删除条目' -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

2 个答案:

答案 0 :(得分:0)

这一切都非常可行,但如果你的源表中有一个唯一的密钥,那将会变得更加容易。通过这种方式,您可以使用某种方法来抛弃它。

我建议,因为这是数据迁移,可能是一次性/有问题的任务,您考虑将其分解为步骤。我不打算给你工作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

当我运行它时,它会找到每个已取消项目的最佳匹配,使用日期顺序选择有多个候选项的最佳选项。如果我要选择CTE(BestMatch)的结果,那么我会看到它是如何工作的:

DATE_TIME   SPECIE_CODE LOAD    LOAD_LIMIT  THICKNESS   GRADE_CODE  SURFACE_MEASURE FBM LOG_COUNT   MATCHED_DATE_TIME   CANDIDATE_MATCHED_DATE_TIME MATCH_ID
2016-12-01 10:40:52.000 ASH 850-OHP 15000   4/4 Sel -13 -13 -1  NULL    2016-12-01 10:40:46.000 1
2016-12-01 11:00:08.000 ASH 850-BSI2    10000000    6/4 1Com    -10 -15 -1  NULL    2016-12-01 10:59:54.000 1
2016-12-01 11:00:08.000 ASH 850-BSI2    10000000    6/4 1Com    -10 -15 -1  NULL    2016-12-01 10:52:39.000 2

第一次取消是针对LOAD值为850-OHP的行,这里只有一个候选者,所以没问题。第二次取消是针对LOAD值为850-BS12的行,这次有两个可能的匹配。我们对这些进行排序,并为每一个分配一个MATCH_ID,该MATCH_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;

答案 1 :(得分:0)

首先,获取表中出现count = -1的所有SPECIE_CODE,LOAD,LOAD_LIMIT和THICKNESS值的列表。这些都是删除'SPECIE_CODE,LOAD,LOAD_LIMIT和THICKNESS值。然后删除具有此类值的所有行。它将删除所有这些,无论它们的计数值如何:

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)