SQL中的游标(?):遍历WHERE-Statement中的表

时间:2014-08-22 15:11:29

标签: sql sql-server cursor

目前我遇到了SQL问题。我正在使用SQL Server 2014。

一些背景知识:我将.csv个文件中的大量天气数据上传到名为dbo.import的表中。因为数据没有调整/纠正所以我选择了大部分" text"作为数据类型。

我识别了许多重复行,并将其写在名为dbo.duplikate

的新表中
INSERT INTO dbo.duplikate 
    SELECT 
       airportCode, CAST(DateUTC AS VARCHAR(25)), Count(*) 
   FROM 
       dbo.import
   GROUP BY 
       airportCode, CAST(DateUTC AS VARCHAR(25))
   HAVING 
       Count(*) > 1 

(也许有一种方法可用于如何通过类似的语句在新表中写入所有行,因此我不需要游标(?)?)

现在我尝试在一个新表中写入包含所有行(总共16个)的所有重复项。

我的想法是遍历我的行dbo.duplikate行,并在我的WHERE子句中进行比较。

像这样的东西(伪代码):

INSERT INTO dbo.newTable
   SELECT * 
   FROM dbo.import
   WHERE dbo.import.DateUTC LIKE dbo.duplikate.DateUTC[i] 
     AND dbo.import.airportCode LIKE dbo.duplikate.airportCode[i]

通过谷歌我找到了游标。但我不确定这是不是正确的方法。每次尝试都失败了,因为我不知道如何将行分配给我的WHERE子句...

此致 儒略

1 个答案:

答案 0 :(得分:1)

你的问题中没有任何东西让我相信你需要一个光标。游标可能非常有用,但是当您对数据集执行操作而不是循环时,性能几乎总是更好。

在SQL Server中,您可以使用ROW_NUMBER()或窗口COUNT()来识别重复项,而不会像查询中那样丢失详细信息:

;with cte AS (SELECT *,ROW_NUMBER() OVER(PARTITION BY airportCode, CAST(DateUTC AS VARCHAR(25)) ORDER BY airportCode) RN
                      ,COUNT(*) OVER(PARTITION BY airportCode, CAST(DateUTC AS VARCHAR(25))) Dup_CT
              FROM dbo.import)
SELECT *
FROM cte

从那里,您可以添加WHERE条件以满足您的需求,例如,如果您只想将所有具有重复的记录放入您使用WHERE Dup_CT > 1的新表中。如果要删除重复记录,也可以从cte DELETE

;with cte AS (SELECT *,ROW_NUMBER() OVER(PARTITION BY airportCode, CAST(DateUTC AS VARCHAR(25)) ORDER BY airportCode) RN
                      ,COUNT(*) OVER(PARTITION BY airportCode, CAST(DateUTC AS VARCHAR(25))) Dup_CT
              FROM dbo.import)
DELETE FROM cte
WHERE RN > 1

您可以调整ORDER BY函数中的ROW_NUMBER()子句,以指定在执行上述DELETE时您将保留哪条记录。