合并两组数据并确定哪些是新的,哪些是旧的

时间:2014-08-18 20:18:59

标签: sql sql-server sql-server-2008 tsql

我有两组具有相同字段的数据:

+----+---------+-------------+
| PK | myCDKey | DateCreated |
+----+---------+-------------+
|  1 |  131048 | 8/18/2014   |
|  2 |  131049 | 8/18/2014   |
|  3 |  131050 | 8/18/2014   |
|  4 |  131051 | 8/18/2014   |
|  5 |  131052 | 8/18/2014   |
|  6 |  131053 | 8/18/2014   |
|  7 |  131054 | 8/18/2014   |
|  8 |  131055 | 8/18/2014   |
|  9 |  131058 | 8/18/2014   |
| 10 |  131059 | 8/18/2014   |
+----+---------+-------------+

+----+---------+-------------+
| PK | myCDKey | DateCreated |
+----+---------+-------------+
| 11 |  131048 | 8/19/2014   |
| 12 |  131049 | 8/19/2014   |
| 13 |  131053 | 8/19/2014   |
| 14 |  131054 | 8/19/2014   |
| 15 |  131055 | 8/19/2014   |
| 16 |  131058 | 8/19/2014   |
| 17 |  131059 | 8/19/2014   |
| 18 |  111111 | 8/19/2014   |
| 19 |  222222 | 8/19/2014   |
| 20 |  333333 | 8/19/2014   |
+----+---------+-------------+

我想要的输出是这样的:

+----+---------+------------+
| PK | myCDKey | Delete/Add |
+----+---------+------------+
|  3 |  131050 | delete     |
|  4 |  131051 | delete     |
|  5 |  131052 | delete     |
| 18 |  111111 | add        |
| 19 |  222222 | add        |
| 20 |  333333 | add        |
+----+---------+------------+

输出显示,在比较两个日期时,最近的行动是删除了3张CD,并添加了3张。

使用合并功能是否已经有了开箱即用的方法?

感谢@Linger指出我应该解释我们是如何知道他们被添加/删除的。

  

补充:如果myCDKey存在于最近的日期,而不是   上一个日期,然后它被添加。

     

已删除:如果myCDKey存在于上一个日期,但不存在于   最近的

请注意,在比较2个数据集时,我们只会有2个日期(如此处的示例,我们只有8/18和8/19)

4 个答案:

答案 0 :(得分:1)

这样做:

minus Tbl1 from Tbl2 : added records , add Delete/Add as 'add'
union
minus Tbl2 from Tbl1 : deleted records, add Delete/Add as 'delete'

在sql server

中使用except

答案 1 :(得分:1)

select y.pk, x.mycdkey, 'delete' as delete_or_add
  from (select mycdkey
          from tbl1 except
                select mycdkey from tbl2
        ) x
  join tbl1 y
    on x.mycdkey = y.mycdkey
union all
select y.pk, x.mycdkey, 'add' as delete_or_add
  from (select mycdkey
          from tbl2 except
                select mycdkey from tbl1
        ) x
  join tbl2 y
    on x.mycdkey = y.mycdkey

小提琴: http://sqlfiddle.com/#!3/ac1a7/6/0

答案 2 :(得分:1)

SQL Fiddle

SELECT m1.PK, m1.myCDKey, 'delete' AS `DELETE/ADD`
FROM MyTable1 m1 
WHERE m1.myCDKey NOT IN 
(
   SELECT t2.myCDKey
   FROM MyTable2 t2
)
UNION
SELECT m2.PK, m2.myCDKey, 'add' AS `DELETE/ADD`
FROM MyTable2 m2
WHERE m2.myCDKey NOT IN 
(
   SELECT t1.myCDKey
   FROM MyTable1 t1
);

或者您可以执行类似(SQL Fiddle)的操作:

SELECT m1.PK, m1.myCDKey, 'delete' AS `DELETE/ADD`
FROM MyTable1 m1 
LEFT JOIN MyTable2 m2 ON m1.myCDKey = m2.myCDKey 
WHERE m2.myCDKey IS NULL
UNION
SELECT m2.PK, m2.myCDKey, 'add' AS `DELETE/ADD`
FROM MyTable1 m1 
RIGHT JOIN MyTable2 m2 ON m1.myCDKey = m2.myCDKey 
WHERE m1.myCDKey IS NULL

答案 3 :(得分:1)

使用FULL JOIN的版本是:

select coalesce(m1.PK,m2.PK) PK
, coalesce(m1.myCDKey, m2.myCDKey) myCDKey
, case 
  when m1.PK is null then 'add' 
  when m2.PK is null then 'delete' else 'error' 
end as action
from MyTable1 m1
FULL OUTER JOIN MyTable2 m2 ON m1.myCDKey = m2.myCDKey 
WHERE m1.PK is null or m2.PK is null

小提琴在这里:SQL Fiddle