如何加入行SQL?
How to Join Rows SQL?
很难解释我的问题,所以我添加了一张图片。
历史记录:
我在 tblother
中有 ReportedGMY
列。我需要将值更新为 ReportedGMY
并且我必须保存 tblhistory
旧的 ReportedGMY
值和新的 ReportedGMY
值。
首先,我执行了 INSERT INTO SELECT
查询并从 tblother
保存到 tblhistory
ReportedGMY
值。我更新了 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
,我想问题就会得到解决。你怎么看?
我在这里使用子查询 return 只是 FindingID
和 OldValue
,其中 OldValue
IS NOT NULL
。这些值随后用于更新 OldValue
.
中具有 NULL
的行
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
然后您可以像这样在 ChangeArea 中使用 null
删除数据
DELETE FROM TableName
WHERE ChangeArea IS NULL
另一种选择是将所有数据提取到临时 table,截断 table,然后重新插入数据。像这样(假设您的 ID 字段是 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 肯定只有一行。缺点是,如果您的 table 很大,那么您将非常努力地使用 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'
这是一个可更新的 CTE 的建议。这是完全未经测试的空气代码...没有保证...
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;
很难解释我的问题,所以我添加了一张图片。
历史记录:
我在 tblother
中有 ReportedGMY
列。我需要将值更新为 ReportedGMY
并且我必须保存 tblhistory
旧的 ReportedGMY
值和新的 ReportedGMY
值。
首先,我执行了 INSERT INTO SELECT
查询并从 tblother
保存到 tblhistory
ReportedGMY
值。我更新了 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
,我想问题就会得到解决。你怎么看?
我在这里使用子查询 return 只是 FindingID
和 OldValue
,其中 OldValue
IS NOT NULL
。这些值随后用于更新 OldValue
.
NULL
的行
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
然后您可以像这样在 ChangeArea 中使用 null
删除数据
DELETE FROM TableName
WHERE ChangeArea IS NULL
另一种选择是将所有数据提取到临时 table,截断 table,然后重新插入数据。像这样(假设您的 ID 字段是 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 肯定只有一行。缺点是,如果您的 table 很大,那么您将非常努力地使用 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'
这是一个可更新的 CTE 的建议。这是完全未经测试的空气代码...没有保证...
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;