2015-09-23 2 views
0

Я пытаюсь вставить записи из старой таблицы в новую версию той же таблицы. Проблема в том, что старая таблица была сделана около 16 лет назад самим пользователем базы данных базы данных, который явно пропустил внешние ключи (поэтому каждая таблица имеет первичный ключ для автонабора, и нет ограничений целостности). Я хотел бы взять все записи и вставить их в мой стол, который таблица имеет следующий ключ:SQL Server 2008 Вставить не дубликаты из запроса подсчета

(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)) 

Но до сих пор не возвращающей никаких значений ...

+1

'КОГДА F.DontBookTime_Date <> NULL' будет ** всегда ** быть ложным - вы не можете использовать нормальное равенство и неравенство операторов с' NULL' - вы можете ** только ** проверить 'IS NULL' или' IS NOT NULL' против потенциального значения NULL ... –

+0

Ах да, я продолжаю делать эту ошибку в SQL. Я исправил это, но он все еще приводит к 0 строкам с таким большим вставным запросом –

ответ

1

Во-первых, Вы сделали ошибку в WHERE пункте Ваше состояние

WHERE NOT EXISTS (SELECT ...) 

может быть только истинным или ложным (зависит от того, возвращает какие-либо записи вашего SELECT ... или нет), но вы пытаетесь фильтровать записи с булевой статьи ,

Во-вторых, 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 
0

Вы можете использовать это, чтобы перекрестно check: Заменить '' на -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)) 
Смежные вопросы