我有2个SQLite表(其中一个是临时的),我需要知道它们内容的差异(旧数据与新数据)。如果需要,我可以使用多个查询,我将在下面解释:
Table structure:
- id INTEGER PRIMARY KEY
- data TEXT NOT NULL
我们假设旧数据是:
Table "olddata"
id - data
1 - abc
2 - def
3 - ghi
4 - jkl
新数据(临时表)是:
Table "newdata"
id - data
1 - test
3 - ghi
5 - mno
6 - pqr
我需要知道的是:
1 was updated
2 was deleted
3 had no change
4 was deleted
5 was include
6 was include
我是SQL新手,特别是SQLite。根据我有限的知识,意识形态是做3个不同的查询:
Get included records:
- Select all "ids" from newdata that are not in olddata
Get removed records:
- Select all "ids" from olddata that are not in newdata
Get updated records:
- Select all same "ids" from olddata AND newdata, with different data field content
我已经研究过,发现有些人使用LEFT JOIN,其他人使用EXCEPT,其他使用NOT IN ...请问,有人可以用最好的方法帮助我解决这些问题吗?
谢谢!
答案 0 :(得分:1)
我认为简单的Union All
和条件聚合可以解决问题
Select ID
,max(case when Src=1 then ID else null end) as Old_ID
,max(case when Src=2 then ID else null end) as New_ID
,max(case when Src=1 then Data else null end) as Old_Data
,max(case when Src=2 then Data else null end) as New_Data
,case when count(*)=2 and min(data)=max(data) then 'No Change'
when count(*)=2 and min(data)<>max(data) then 'Updated'
when count(*)=1 and max(Src)=1 then 'Deleted'
when count(*)=1 and max(Src)=2 then 'Added'
else null end as Status
From (
Select 1 as Src,Old_ID as ID,Old_Data as Data From OldData
Union All
Select 2 as Src,New_ID as ID,New_Data as Data From NewData
) A
Group By A.ID
答案 1 :(得分:0)
full join
就是这种情况。但是,SQLite并不支持它。所以你必须用3个查询来完成它。
--value changed or not
select o.id,case when o.val <> n.val then 'updated'
when o.val = n.val then 'no change'
end as changetype
from olddata o
join newdata n on n.id=o.id
union all
--deleted records
select o.id,'deleted' as changetype
from olddata o
left join newdata n on n.id=o.id
where n.id is null
union all
--added records
select n.id,'added' as changetype
from newdata n
left join olddata o on n.id=o.id
where o.id is null
答案 2 :(得分:0)
添加的ID是那些未出现在旧数据中的ID:
SELECT id FROM newdata WHERE id NOT IN (SELECT id FROM olddata);
已删除的ID是那些未出现在新数据中的ID:
SELECT id FROM olddata WHERE id NOT IN (SELECT id FROM newdata);
可以通过获取两个表中都存在ID的所有行,然后使用compound SELECT语句删除所有相同的行来确定更改的行:
SELECT * FROM newdata WHERE id IN (SELECT id FROM olddata)
EXCEPT
SELECT * FROM olddata;
如果你想获得所有未更改的行,你可以简单地使用intersection:
SELECT * FROM newdata
INTERSECT
SELECT * FROM olddata;
(这些查询适用于任意数量的数据列。)