SQL Server 2008从计数查询中插入非重复项

时间:2015-09-23 04:53:52

标签: sql sql-server sql-server-2008

我正在尝试将旧表中的记录插入到同一个表的新版本中。问题是旧桌子大约是16年前由一个自学成才的数据库人员制作的,他显然跳过了外键(因此每个表都有一个自动编号主键,并且没有完整性限制)。我希望获取所有记录并将它们插入到我的表中,该表具有以下键:

(ProjectID, SubProjectID, PhaseID, SubPhaseID, DisciplineID)

我做了一个快速查询,分组并计算旧表中的上述键,我得到480条记录,基本上是我新表中的一个非唯一键。

我的问题:是否可以创建一个查询来获取我的计数查询中没有出现的所有行并将它们插入到新表中?因为我的计数查询是在5个字段上进行分组,我希望插入17个字段的完整记录。

到目前为止,我的尝试返回了0条记录,所以我希望能够接近。 此外,我在SO上已经找不到任何内容,所以如果这是重复的话,请道歉

INSERT INTO [ERP].[dbo].[Fees]
           ([ProjectID]
           ,[SubProjectID]
           ,[PhaseID]
           ,[SubPhaseID]
           ,[DisciplineID]
           ,[DatePhaseCommenced]
           ,[TotalFee]
           ,[EnggFee]
           ,[DraftFee]
           ,[ProposalDate]
           ,[Comment]
           ,[AuthDate]
           ,[AuthDescription]
           ,[HourlyRate]
           ,[Closed]
           ,[ClosedDate]
           ,[SubmissionDate])
     SELECT 
         F.ProjectNo, 1, F.PhaseID, F.SubPhase, F.DisciplineID, '1/1/2000', 
         F.Amount, F.Engineering, F.Drafting, F.[Proposal Date],
         F.Comment, F.AuthDate, F.AuthDescription, F.HourlyRate, 
         CASE 
             WHEN F.DontBookTime = 1 THEN 1 
             WHEN F.DontBookTime_Date IS NOT NULL THEN 1 
             ELSE 0 
         END, 
         F.DontBookTime_Date, F.SubmissionDate 
     FROM 
         Multitech.dbo.Fees F 
     WHERE 
         NOT EXISTS (SELECT 
                         F.ProjectNo, F.PhaseID, F.SubPhase, F.DisciplineID 
                     FROM Multitech.dbo.Fees F 
                     WHERE (F.Amount > 0 OR F.Engineering > 0 OR F.Drafting > 0) 
                     GROUP BY 
                         F.ProjectNo, F.PhaseID, F.SubPhase, F.DisciplineID 
                      HAVING (COUNT(*) > 1))
GO

UPDATE ::

我意识到我只能在我的查询中不存在的主键上插入,然后使用适当的值从原始更新。该查询也有轻微问题。

选择重复查询:

SELECT F.ProjectNo, F.PhaseID, F.SubPhase, F.DisciplineID 
FROM Multitech.dbo.Fees F 
GROUP BY F.ProjectNo, F.PhaseID, F.SubPhase, F.DisciplineID 
HAVING (COUNT(*) > 1)

然后选择不在重复查询中的所有内容:

SELECT F.ProjectNo, F.PhaseID, F.SubPhase, F.DisciplineID 
FROM Multitech.dbo.Fees F 
WHERE NOT EXISTS (SELECT 
                      F.ProjectNo, F.PhaseID, F.SubPhase, F.DisciplineID  
                  FROM Multitech.dbo.Fees F 
                  GROUP BY 
                      F.ProjectNo, F.PhaseID, F.SubPhase, F.DisciplineID 
                  HAVING (COUNT(*) > 1))

但仍然没有返回值......

2 个答案:

答案 0 :(得分:1)

首先,你在WHERE条款中犯了一个错误 你的病情

WHERE NOT EXISTS (SELECT ...)

只能是true或false(取决于是否返回您SELECT ...的任何记录),但是您尝试使用boolean子句过滤记录。

其次,WHERE NOT EXISTS .. HAVING (COUNT(*) > 1)HAVING (COUNT(*) = 1)相同,我是对的吗?

第三,使用JOIN表而不是WHERE NOT EXISTS

    SELECT 
             F.ProjectNo, 1, F.PhaseID, F.SubPhase, F.DisciplineID, '1/1/2000', 
             F.Amount, F.Engineering, F.Drafting, F.[Proposal Date],
             F.Comment, F.AuthDate, F.AuthDescription, F.HourlyRate, 
             CASE 
                 WHEN F.DontBookTime = 1 THEN 1 
                 WHEN F.DontBookTime_Date IS NOT NULL THEN 1 
                 ELSE 0 
             END, 
             F.DontBookTime_Date, F.SubmissionDate 
         FROM 
             Multitech.dbo.Fees F 
         JOIN 
             (SELECT    F.ProjectNo, F.PhaseID, F.SubPhase, F.DisciplineID 
                         FROM Multitech.dbo.Fees F 
                         WHERE (F.Amount > 0 OR F.Engineering > 0 OR F.Drafting > 0) 
                         GROUP BY 
                             F.ProjectNo, F.PhaseID, F.SubPhase, F.DisciplineID 
                          HAVING (COUNT(*) = 1)) as Count_F 
         ON F.ProjectNo = Count_F.ProjectNo and F.PhaseID = Count_F.PhaseID 
        and F.SubPhase = Count_F.SubPhase and F.DisciplineID = Count_F.DisciplineID

答案 1 :(得分:0)

您可以使用它来交叉检查:将''替换为-1表示整数

SELECT F.ProjectNo, F.PhaseID, F.SubPhase, F.DisciplineID 
FROM Multitech.dbo.Fees F 
WHERE NOT EXISTS (SELECT 1 FROM Multitech.dbo.Fees X
where 
Isnull( F.ProjectNo,'') =  Isnull( X.ProjectNo,'') and  
Isnull( F.PhaseID,'') = Isnull( X.PhaseID,'')  and  
Isnull( F.SubPhase,'') = Isnull( X.SubPhase,'') and  
Isnull( F.DisciplineID ,'') = Isnull( X.DisciplineID ,'') 
GROUP BY 
 X.ProjectNo, X.PhaseID, X.SubPhase, X.DisciplineID 
 HAVING (COUNT(*) > 1))