2016-07-01 4 views
2

Трудно объяснить мою проблему, поэтому я добавил изображение.Как присоединиться к строкам SQL?

tblhistory:

tblhistory

У меня есть ReportedGMY колонку в tblother. Мне нужно обновить значения до ReportedGMY, и мне нужно сэкономить в tblhistory старых ReportedGMY значения и новых ReportedGMY значения.

Во-первых, я выполнил запрос INSERT INTO SELECT и сэкономьте до tblhistoryReportedGMY значение от tblother. И я обновил tblother и изменил значения. Затем я снова вставил в tblhistory.

Теперь мне нужно передать значения OldValue с запросом. Затем удалите нулевые строки. Как это можно сделать? Или по-другому?

Вставка (второй) запрос:

INSERT INTO tblhistory(FindingID, NewValue, [Date]) 
    SELECT 
     ID, ReportedGMY, GETDATE() AS CurrentDateTime 
    FROM 
     (SELECT 
      ID, tblother.ReportedGMY, 
      REPLACE(tblother.ReportedGMY, ' ', '') AS NewNumbers 
     FROM 
      tblother 
     INNER JOIN 
      tblother2 ON tblother.ReportID = tblother2.ID) A 
    WHERE 
     A.ReportedGMY LIKE '%,Y,%' 
     OR A.ReportedGMY LIKE 'Y,%' 
     OR A.ReportedGMY LIKE '%,Y' 

Если я могу написать этот запрос как UPDATE, проблема будет решена, я думаю. Как вы думаете?

ответ

1

Я использовал подзапрос здесь, чтобы вернуть только FindingID и OldValue, где OldValueIS NOT NULL. Эти значения затем используются для обновления строк, которые имеют NULL в OldValue.

UPDATE a 
SET a.OldValue = b.OldValue 
FROM TableName a 
INNER JOIN (SELECT FindingID, OldValue FROM TableName where OldValue IS NOT NULL) b 
    ON a.FindingID = b.FindingID 
WHERE a.OldValue IS NULL 

Вы можете избавиться от данных с null в ChangeArea как этот

DELETE FROM TableName 
WHERE ChangeArea IS NULL 

Другим вариантом было бы извлечь все данные в временную таблицу, усечь таблицу, а затем повторно вставить данные. Что-то вроде этого (при условии, что ваш идентификатор поля является IDENTITY поле, как оно появляется)

SELECT 
FindingID 
,MAX(ChangeArea) ChangeArea 
,MAX(OldValue) OldValue 
,MAX(NewValue) NewValue 
,MAX(Date) Date 
INTO #TempTable 
FROM TableName 
GROUP BY FindingID 

TRUNCATE TABLE TableName 

INSERT INTO TableName (FindingID, ChangeArea, OldValue, NewValue, Date) 
SELECT 
FindingID 
,ChangeArea 
,OldValue 
,NewValue 
,Date 
FROM #TempTable 

DROP TABLE #TempTable 

Преимущество этого будет то, что вы определенно будете только одну строку для каждого FindingID. Недостатком является то, что если ваша таблица большая, то вы будете сильно ударять по tempdb, и это может занять некоторое время.

Редактировать: Чтобы изменить этот второй оператор на обновление, вам нужно что-то подобное;

UPDATE a 
SET 
    a.ChangeArea = b.ReportedGMY 
    ,a.NewValue = REPLACE(b.ReportedGMY, ' ','') 
    ,a.Date = GETDATE() 
FROM tblhistory a 
INNER JOIN tblother b 
    ON a.FindingID = b.FindingID 
WHERE b.ReportedGMY like '%,Y,%' 
    OR b.ReportedGMY like 'Y,%' 
    OR b.ReportedGMY like '%,Y' 
+0

Это близко к тому, что я собираюсь ответить. Одна вещь, о которой нужно помнить, вероятно, заключается в наличии дублирующих значений «FindingId». Но пока их старые ценности похожи, это, вероятно, приведет лишь к появлению нескольких дополнительных обновлений (хотя я не совсем уверен в этом). –

+0

Да, полностью действительная забота. Я только что обновил свой ответ с помощью решения, которое обязательно вернет только одну строку данных на FindingID –

+0

. Я обновил свой вопрос. – pseudocode

1

Это было предложение с обновляемого КТР. Это полностью непроверенный код воздуха ... нет гарантий ...

WITH ThisToUpdate(FindingIndex,FindingID,OldValue) AS 
(
    SELECT ROW_NUMBER() OVER(PARTITION BY tblother.FindingID ORDER BY tblother.ID) AS FindingIndex 
      ,tblother.FindingID 
      ,tblother.OldValue 
    FROM tblother 
    WHERE tblother.OldValue IS NULL --or tblother.ChangeArea IS NOT NULL 
) 
,ValuesToUpdate(FindingIndex,FindingID,OldValue) AS 
(
    SELECT ROW_NUMBER() OVER(PARTITION BY tblother.FindingID ORDER BY tblother.ID) AS FindingIndex 
      ,tblother.FindingID 
      ,tblother.ChangeArea 
    FROM tblother 
    WHERE tblother.OldValue IS NOT NULL --or tlbother.ChangeArea IS NULL 
) 
,Combined AS 
(
    SELECT t1.* 
      ,t2.OldValue AS NewValue 
    FROM ThisToUpdate AS t1 
    INNER JOIN ValuesToUpdate AS t2 ON t1.FindingID=t2.FindingID AND t1.FindingIndex=t2.FindingIndex 
) 
UPDATE Combined SET OldValue=NewValue; 
Смежные вопросы