我们有一个类似于这样的表: 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
答案 0 :(得分:0)
这一切都非常可行,但如果你的源表中有一个唯一的密钥,那将会变得更加容易。通过这种方式,您可以使用某种方法来抛弃它。
我建议,因为这是数据迁移,可能是一次性/有问题的任务,您考虑将其分解为步骤。我不打算给你工作SQL,因为我没有从你的问题中得到足够的信息,但这就是我要开始的方式:
如果您没有任何唯一的密钥,那么我甚至会考虑临时创建一个密钥,因为这样可以更容易。你可以这样做:
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)