【问题标题】:one table to another table insert without duplicate record一张表插入另一张表没有重复记录
【发布时间】:2017-06-01 13:55:00
【问题描述】:

我想将数据从表 T1 复制到表 T2,条件如下: 1)数据不应重复。 2)T1-Checkin和T2-checkin列的时间差必须大于5秒。

我现有的程序这个

ALTER PROCEDURE [dbo].[usp_InsertUserAttendanceLog] @userId varchar(400),@CheckInCheckOutDate datetime,@WorkDate datetime,@InOutMode int,@VerifyMode int, @InsertDate datetime
AS
BEGIN
if 
not exists (select 1 from tblAttendance where CheckInCheckOutDate=@CheckInCheckOutDate and WorkDate=@WorkDate and InOutMode=@InOutMode and VerifyMode=@VerifyMode )
begin
if
not exists (select 1 from tblAttendance where empCode=@userId and convert(date,CheckInCheckOutDate)=convert(date,@CheckInCheckOutDate) and DATEDIFF(second,CheckInCheckOutDate,@CheckInCheckOutDate) <= 3)
begin
 INSERT INTO tblAttendance(EmpCode,CheckInCheckOutDate,WorkDate,InoutMode,VerifyMode,InsertDate)
 VALUES(@userId,@CheckInCheckOutDate,@WorkDate,@InOutMode,@VerifyMode,@InsertDate)
 end
 end
end

我尝试了这样的代码,但不起作用。得到重复

INSERT INTO tblAttendance (EmpCode,CheckInCheckOutDate,WorkDate,InOutMode,VerifyMode,InsertDate,[Status])
SELECT T1.EmpCode,T1.CheckInCheckOutDate,T1.WorkDate,T1.InOutMode,T1.VerifyMode,T1.InsertDate,T1.[Status]
  FROM testAttendanceBulk T1
 WHERE NOT EXISTS(select 1 from tblAttendance T2 where T2.CheckInCheckOutDate=T1.CheckInCheckOutDate
 and T2.WorkDate=T1.WorkDate and T2.InOutMode=T1.InOutMode 
 and T2.VerifyMode=T1.VerifyMode and T2.empCode=T1.EmpCode 
 and convert(date,T2.CheckInCheckOutDate)=convert(date,T1.CheckInCheckOutDate) 
 and DATEDIFF(second,T2.CheckInCheckOutDate,T1.CheckInCheckOutDate) <= 5)  

it's my table structure

【问题讨论】:

  • 你能定义“不工作”吗?你得到重复?你什么都得不到吗?您收到错误消息了吗?
  • @Sean Lange 重复感谢
  • 不要害怕在查询中添加一些空格,这样它们更易于阅读。文本 sql 的墙很难使用。您的哪个查询返回重复项?两个都?第一个?第二个?请记住,我们看不到您的屏幕或读懂您的想法。我们可以提供帮助,但您必须向我们提供信息。这是一个很好的起点。 spaghettidba.com/2015/04/24/…
  • @ Sean Lange 第一个程序运行良好,但它正在逐个输入,现在我希望它像第二个代码一样执行,其中它从一个表复制到另一个表命令谢谢。

标签: sql sql-server sql-server-2008 sql-server-2012 sql-server-2008-r2


【解决方案1】:

很确定你可以使用这样的东西。请注意我对 DATEFIFF 谓词的评论,这可能是您面临的问题的一部分。

INSERT INTO tblAttendance 
(
    EmpCode
    , CheckInCheckOutDate
    , WorkDate
    , InOutMode
    , VerifyMode
    , InsertDate
    , [Status]
)
SELECT ab.EmpCode
    , ab.CheckInCheckOutDate
    , ab.WorkDate
    , ab.InOutMode
    , ab.VerifyMode
    , ab.InsertDate
    , ab.[Status]
FROM testAttendanceBulk ab
LEFT JOIN tblAttendance a ON a.CheckInCheckOutDate = ab.CheckInCheckOutDate
    AND a.WorkDate = ab.WorkDate 
    AND a.InOutMode = ab.InOutMode 
    AND isnull(a.VerifyMode, 0) = isnull(ab.VerifyMode, 0) 
    AND a.empCode = ab.EmpCode 
    AND CONVERT(DATE, a.CheckInCheckOutDate) = CONVERT(DATE, ab.CheckInCheckOutDate) 
    AND DATEDIFF(SECOND, a.CheckInCheckOutDate, ab.CheckInCheckOutDate) <= 5 --do you really want 5 here? Your original query had 3.
WHERE a.empCode IS NULL

【讨论】:

  • 好的,很好。你试过这个查询吗?
  • 如果我执行消息(受影响的 100 行)则不起作用如果我再次执行显示(受影响的 100 行)它让我受够了。谢谢
  • 好吧,如果您像我之前建议的那样发布表结构和一些示例数据,这对其他人来说会更容易提供帮助。我们正在盲目地编写查询。
  • @Sean Lange 确定这是我的表格结构rextester.com/JVYQ44588 谢谢
  • 这是因为您在 VerifyMode 中有 NULL 并且相等检查将失败。您可以轻松地将它们包装在 ISNULL 或 COALESCE 中。您应该对允许 NULL 的其他列执行相同的操作。请参阅我的更新答案。
【解决方案2】:

在您的加入中,您正在检查 CheckinCheckoutDate 是否相等,以及是否存在 >5 秒的差异。尝试摆脱 t1.CheckinCheckoutDate = T2.CheckinCheckoutDate;

 INSERT
      INTO tblAttendance 
           (EmpCode,
            CheckInCheckOutDate,
            WorkDate,
            InOutMode,
            VerifyMode,
            InsertDate,
            [Status])
    SELECT
  DISTINCT T1.EmpCode,
           T1.CheckInCheckOutDate,
           T1.WorkDate,
           T1.InOutMode,
           T1.VerifyMode,
           T1.InsertDate,
           T1.[Status]
      FROM testAttendanceBulk T1
     WHERE NOT EXISTS(SELECT T1.EmpCode,
                             T1.CheckInCheckOutDate,
                             T1.WorkDate,
                             T1.InOutMode,
                             T1.VerifyMode,
                             T1.InsertDate,
                             T1.[Status]
                        FROM tblAttendance T2
                       WHERE 1=1 --T2.CheckInCheckOutDate=T1.CheckInCheckOutDate
                         AND T2.WorkDate=T1.WorkDate 
                         AND T2.InOutMode=T1.InOutMode 
                         AND T2.VerifyMode=T1.VerifyMode
                         AND T2.empCode=T1.EmpCode 
                         AND convert(date,T2.CheckInCheckOutDate)=convert(date,T1.CheckInCheckOutDate) 
                         AND DATEDIFF(second,T2.CheckInCheckOutDate,T1.CheckInCheckOutDate) <= 5)  

【讨论】:

  • 如果我执行消息(受影响的 100 行)如果我再次执行显示(受影响的 100 行),我受够了。谢谢
  • 好的,所以从您的评论中我了解到您不想插入重复项,在这种情况下,您可以加入要插入的表。让我尝试更新代码。
  • 更新了我的代码,你正在做 T2.CheckInCheckOutDate=T1.CheckInCheckOutDate AND AND DATEDIFF(second,T2.CheckInCheckOutDate,T1.CheckInCheckOutDate) 0,则它们不能相等。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-31
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 2019-08-30
  • 2017-08-23
  • 2013-04-22
相关资源
最近更新 更多