Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我的SQL循环需要很长时间才能完成。有没有更好的方法来实现我的目标?_Sql_Sql Server_Tsql_While Loop - Fatal编程技术网

我的SQL循环需要很长时间才能完成。有没有更好的方法来实现我的目标?

我的SQL循环需要很长时间才能完成。有没有更好的方法来实现我的目标?,sql,sql-server,tsql,while-loop,Sql,Sql Server,Tsql,While Loop,我正在尝试基于某些列对一组数据进行重复数据消除。也就是说,它不像只选择DISTINCT那么简单 我想从集合中选择列唯一的所有行。我对我的集合进行了排序,我只希望循环获取代理键列的第一个匹配项。我说的是proxy,因为它不是表的实际主键 我使用了while循环,并使用了一个基于临时表中行数的计数器变量。我在处理后从临时表中删除了每一行,这样就可以减少基础表中处理的一条记录和任何重复的行 虽然我的代码很好用,但它看起来很“牛仔气”,我想听听你对如何做到“更干净”的意见,谢谢 这是我的密码: decl

我正在尝试基于某些列对一组数据进行重复数据消除。也就是说,它不像只选择DISTINCT那么简单

我想从集合中选择列唯一的所有行。我对我的集合进行了排序,我只希望循环获取代理键列的第一个匹配项。我说的是proxy,因为它不是表的实际主键

我使用了while循环,并使用了一个基于临时表中行数的计数器变量。我在处理后从临时表中删除了每一行,这样就可以减少基础表中处理的一条记录和任何重复的行

虽然我的代码很好用,但它看起来很“牛仔气”,我想听听你对如何做到“更干净”的意见,谢谢

这是我的密码:

declare @cnt int

set @cnt = (select COUNT(*) from #temp)

while @cnt > 0
begin       
    select top 1 * into #temp2 from #temp

    insert into #temp3 (Member_ID, email, meeting_status,member_type,firstname,lastname,address1, Match_Method, Match_Score)
        select #temp2.* 
        from #temp2
        left outer join #temp3 on #temp2.Member_ID = #temp3.Member_ID
        where #temp3.Member_ID is null

    delete #temp 
    from #temp
    inner join #temp2 on #temp.Member_ID = #temp2.Member_ID

    drop table #temp2

    set @cnt = (select COUNT(*) from #temp)
end

如果我正确理解了您的需求,那么您希望将temp中的行插入temp3,但您希望确保只插入同一成员的一行。在这种情况下,您可以使用ROW_NUMBER和filter for ROW_NUMBER=1来确保只插入重复成员ID中的一行。然后添加“不存在”筛选器以避免插入已存在的行:

INSERT INTO #temp3 (Member_ID, email, meeting_status, member_type, firstname, lastname, address1, Match_Method, Match_Score)
    SELECT
        Member_ID,
        email,
        meeting_status,
        member_type,
        firstname,
        lastname,
        address1,
        Match_Method,
        Match_Score
    FROM (
        SELECT *,
            Rn = ROW_NUMBER() OVER (PARTITION BY Member_ID ORDER BY (SELECT NULL))
        FROM #temp
    ) t
    WHERE
        t.Rn = 1
        AND NOT EXISTS (
            SELECT 1
            FROM #temp3 t3
            WHERE t3.Member_ID = t.MEMBER_ID
        )

如果我正确理解了您的需求,那么您希望将temp中的行插入temp3,但您希望确保只插入同一成员的一行。在这种情况下,您可以使用ROW_NUMBER和filter for ROW_NUMBER=1来确保只插入重复成员ID中的一行。然后添加“不存在”筛选器以避免插入已存在的行:

INSERT INTO #temp3 (Member_ID, email, meeting_status, member_type, firstname, lastname, address1, Match_Method, Match_Score)
    SELECT
        Member_ID,
        email,
        meeting_status,
        member_type,
        firstname,
        lastname,
        address1,
        Match_Method,
        Match_Score
    FROM (
        SELECT *,
            Rn = ROW_NUMBER() OVER (PARTITION BY Member_ID ORDER BY (SELECT NULL))
        FROM #temp
    ) t
    WHERE
        t.Rn = 1
        AND NOT EXISTS (
            SELECT 1
            FROM #temp3 t3
            WHERE t3.Member_ID = t.MEMBER_ID
        )
在循环中,您不必每次都重新计算表的数量。您可以简单地减少@cnt。 您不应该每次在循环中都重新创建temp2。你可以重复使用它 您根本不必使用temp2。您只需使用select top 1*from temp即可 您根本不必使用循环,只需使用以下脚本即可:

insert into #temp3(Member_ID, email, meeting_status, member_type, firstname, lastname, address1, Match_Method, Match_Score)
    select * 
    from #temp
    where Member_ID not in (select Member_ID from #temp3)
在循环中,您不必每次都重新计算表的数量。您可以简单地减少@cnt。 您不应该每次在循环中都重新创建temp2。你可以重复使用它 您根本不必使用temp2。您只需使用select top 1*from temp即可 您根本不必使用循环,只需使用以下脚本即可:

insert into #temp3(Member_ID, email, meeting_status, member_type, firstname, lastname, address1, Match_Method, Match_Score)
    select * 
    from #temp
    where Member_ID not in (select Member_ID from #temp3)
备选案文1:

使用以下代码:

WITH uniqueRecords AS(
    SELECT  *,ROW_NUMBER()OVER(PARTITION BY T.Member_ID ORDER BY (SELECT 1)) AS RowNum
    FROM #Temp AS T
)
INSERT INTO #temp3(Member_ID, email, meeting_status,member_type,firstname,lastname,address1, Match_Method, Match_Score)
SELECT U.Member_ID, U.email, U.meeting_status,U.member_type,U.firstname,U.lastname,U.address1, U.Match_Method, U.Match_Score
FROM uniqueRecords AS U
LEFT OUTER JOIN #temp3 T3 on U.Member_ID = T3.Member_ID
WHERE U.RowNum=1
AND T3.Member_ID is null;
备选案文2:

我使用IGNORE\u DUP\u KEY=on在Member\u ID列的temp3上创建唯一索引

CREATE UNIQUE INDEX UX_temp3 ON #temp3 (Member_ID) WITH (IGNORE_DUP_KEY=ON); 
ii插入temp和temp3左连接的结果。“忽略重复”键选项将忽略重复项

备选案文1:

使用以下代码:

WITH uniqueRecords AS(
    SELECT  *,ROW_NUMBER()OVER(PARTITION BY T.Member_ID ORDER BY (SELECT 1)) AS RowNum
    FROM #Temp AS T
)
INSERT INTO #temp3(Member_ID, email, meeting_status,member_type,firstname,lastname,address1, Match_Method, Match_Score)
SELECT U.Member_ID, U.email, U.meeting_status,U.member_type,U.firstname,U.lastname,U.address1, U.Match_Method, U.Match_Score
FROM uniqueRecords AS U
LEFT OUTER JOIN #temp3 T3 on U.Member_ID = T3.Member_ID
WHERE U.RowNum=1
AND T3.Member_ID is null;
备选案文2:

我使用IGNORE\u DUP\u KEY=on在Member\u ID列的temp3上创建唯一索引

CREATE UNIQUE INDEX UX_temp3 ON #temp3 (Member_ID) WITH (IGNORE_DUP_KEY=ON); 
ii插入temp和temp3左连接的结果。“忽略重复”键选项将忽略重复项


感谢斯拉瓦的评论。但是,如果A在temp中存在两次,它仍将两次插入temp3,因为在生成“set”时,A在temp3中不存在,因此我在插入之前使用循环检查每一行。还是我完全迷路了。。。是否在每次插入后都重新检查temp3?如果temp表有完整的副本,则可以添加DISTINCT。如果重复项不完整,您必须定义规则:将插入哪些记录,哪些不插入。感谢Slava的评论。但是,如果A在temp中存在两次,它仍将两次插入temp3,因为在生成“set”时,A在temp3中不存在,因此我在插入之前使用循环检查每一行。还是我完全迷路了。。。是否在每次插入后都重新检查temp3?如果temp表有完整的副本,则可以添加DISTINCT。如果重复项不完整,则必须定义规则:将插入哪些记录,哪些不插入。是否在每次插入后再次检查“不存在”?@Craigoh1否,它将对整个选择进行评估。我会更新我的答案。我试过了,但它仍然插入了重复项,因此我使用循环和删除。你能解释一下分区位上的行数吗。。我以前从未见过这种情况。thanks@Craigoh1返回结果集中某个分区内的行的序列号,每个分区的第一行从1开始。因此,对ROW_NUMBER=1进行筛选将为每个分区只返回一行。是否在每次插入后再次执行“不存在”检查?@Craigoh1否,它将对整个选择进行评估。我会更新我的答案。我试过了,但它仍然插入了重复项,因此我使用循环和删除。你能解释一下分区位上的行数吗。。我以前从未见过这种情况。thanks@Craigoh1返回结果集中某个分区内的行的序列号,每个分区的第一行从1开始。因此,对ROW_NUMBER=1进行筛选将为每个分区只返回一行。我已以某种方式对集合进行排序。。。。不,不,你没有。您过去可能在任何时候使用过的任何订单都不再相关,除非您存储了
在一列或多列中排序信息时。具体来说,从temp中选择top 1*进入temp2可自由选择temp中的任意行。因此,如果第一个问题很重要,那么你的问题和答案中仍然缺少一些东西。但大多数答案都是一个好的开始。在SQL中,您的第一反应应该始终是如何处理整个集合,而不是逐行。如果我说将排序信息存储在一个或多个列中,我还应该在任何检索操作中说并在ORDER by子句中使用这些列,在这些检索操作中,此排序事项我以某种方式对集合进行了排序。。。。不,不,你没有。您在过去任何时候使用的任何排序都不再相关,除非您已将该排序信息存储在一个或多个列中。具体来说,从temp中选择top 1*进入temp2可自由选择temp中的任意行。因此,如果第一个问题很重要,那么你的问题和答案中仍然缺少一些东西。但大多数答案都是一个好的开始。在SQL中,您的第一反应应该始终是如何处理整个集合,而不是逐行处理。我说的是将排序信息存储在一列或多列中,在任何检索操作中,如果我在查询中注释掉惰性项并选择,那么我也应该在ORDERBY子句中使用这些列,而在您的查询中,这种排序是重要的。。它选择的行数与代码选择的行数完全相同,但只需大约18分钟。但是,插入正在抛出错误。。所以我只是把U.*改成了除RowNum thingy之外的所有字段。@Craigoh1很高兴它起到了作用。我已经编辑了ans。感谢您指出它:在您的查询中,如果我将惰性注释掉并选择。。它选择的行数与代码选择的行数完全相同,但只需大约18分钟。但是,插入正在抛出错误。。所以我只是把U.*改成了除RowNum thingy之外的所有字段。@Craigoh1很高兴它起到了作用。我已经编辑了ans。感谢您指出它: