区分具有相同结构的{2}个表中的内容数据

时间:2017-01-13 20:22:40

标签: sql sqlite

我有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 ...请问,有人可以用最好的方法帮助我解决这些问题吗?

谢谢!

3 个答案:

答案 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;

(这些查询适用于任意数量的数据列。)