【问题标题】:Skip duplicates while importing data into SQL server将数据导入 SQL Server 时跳过重复项
【发布时间】:2016-08-24 07:55:14
【问题描述】:

我正在将 XML 文件数据上传到 SQL Server 数据库。当我再次导入同一个文件时,所有数据行都会重复。

我尝试在删除重复行时使用DISTINCT,但在导入时,数据行仍在重复。

使用DISTINCT方法将数据导入SQL Server数据库时如何跳过重复项?

我的桌子:

Create table HallSeat
(
    HallGroupID int,
    ShowSeatID int,
    Color nvarchar(15),
    Price int,
    SeatRow int,    
    SeatNumber int, 
    IsReserved bit
)

SQL DISTINCT 语句:

SELECT DISTINCT * 
INTO tempdb.dbo.tmpTable
FROM HallSeat

DELETE FROM HallSeat

INSERT INTO HallSeat 
    SELECT * 
    FROM tempdb.dbo.tmpTable

DROP TABLE tempdb.dbo.tmpTable

【问题讨论】:

标签: sql-server duplicates distinct


【解决方案1】:

您可以使用 T-SQL MERGE 语句来执行此操作。它将与您的 HallSeat 表导入的行集相匹配。如果该行不存在,它将插入一个新行。如果该行确实存在并且存在差异,则可以对其进行更新。

(您可能不想执行删除操作,但为了完整起见,我已将其包含在内。)

参见联机丛书 > MERGE (Transact-SQL) -- https://msdn.microsoft.com/en-GB/library/bb510625.aspx

为了演示这一点,首先创建两个表。

CREATE TABLE dbo.HallSeat
(
    HallGroupID int NOT NULL,
    ShowSeatID int NOT NULL,
    Color nvarchar(15) NOT NULL,
    Price int NOT NULL,
    SeatRow int NOT NULL,
    SeatNumber int NOT NULL,
    IsReserved bit NOT NULL,
    CONSTRAINT PK_HallSeat PRIMARY KEY CLUSTERED (HallGroupID, ShowSeatID)
);

CREATE TABLE dbo.ImportHallSeat
(
    HallGroupID int NOT NULL,
    ShowSeatID int NOT NULL,
    Color nvarchar(15) NOT NULL,
    Price int NOT NULL,
    SeatRow int NOT NULL,
    SeatNumber int NOT NULL,
    IsReserved bit NOT NULL,
    CONSTRAINT PK_ImportHallSeat PRIMARY KEY CLUSTERED (HallGroupID, ShowSeatID)
);

然后将 XML 数据文件导入 ImportHallSeat 表中:

-- Read the XML data file to be imported
DECLARE @xml xml;
SELECT @xml = x.a
    FROM OPENROWSET(BULK 'F:\Work\Data.xml', SINGLE_BLOB) AS x(a);

TRUNCATE TABLE dbo.ImportHallSeat;

INSERT INTO dbo.ImportHallSeat(HallGroupID, ShowSeatID, Color, Price, SeatRow, SeatNumber, IsReserved)
    SELECT T.C.value('HallGroupID[1]', 'int') AS 'HallGroupID',
            T.C.value('ShowSeatID[1]', 'int') AS 'ShowSeatID',
            T.C.value('Color[1]', 'nvarchar(15)') AS 'Color',
            T.C.value('Price[1]', 'money') AS 'Price',
            T.C.value('SeatRow[1]', 'int') AS 'SeatRow',
            T.C.value('SeatNumber[1]', 'int') AS 'SeatNumber',
            T.C.value('IsReserved[1]', 'bit') AS 'IsReserved'
        FROM @xml.nodes(N'/Filharmonija/Hall/HallGroup/HallSeat') as T(C);

然后我们可以使用正在导入的数据更新 HallSeat 表:

MERGE
    INTO dbo.HallSeat AS H
    USING dbo.ImportHallSeat AS I
    ON I.HallGroupID = H.HallGroupID AND I.ShowSeatID = H.ShowSeatID
    WHEN MATCHED AND H.Color <> I.Color AND H.Price <> I.Price
        THEN UPDATE SET H.Color = I.Color, H.Price = I.Price
    WHEN NOT MATCHED BY TARGET
        THEN INSERT (HallGroupID, ShowSeatID, Color, Price, SeatRow, SeatNumber, IsReserved)
            VALUES (I.HallGroupID, I.ShowSeatID, I.Color, I.Price, I.SeatRow, I.SeatNumber, I.IsReserved)
    WHEN NOT MATCHED BY SOURCE
        THEN DELETE;

显示已导入 HallSeat 表的数据:

SELECT *
    FROM dbo.HallSeat;

【讨论】:

  • 非常感谢richard345!这是完美的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-26
  • 2017-12-13
  • 1970-01-01
  • 2013-06-08
相关资源
最近更新 更多