【问题标题】:compare two tables and get record new and old values比较两个表并获取记录新旧值
【发布时间】:2019-09-16 21:47:11
【问题描述】:

我有两个表表 A(主表)- 250 列和表 b(历史表)- 240 列, 我需要创建动态查询,因为我的表有 250 列。使用甲骨文

suppose:  Table A(Master table)

ID  Name    City    Phone   Category 
---------------------------------------
111 ABC    Delhi    123456  Red
112 BCD    Mumbai   234987  Green
113 CGU    PUNE     987456  Black

suppose:  Table B(History table)



 ID  City   Phone   Category 
 ---------------------------------
 111 Kerala 123456  White 
 113 Jammu  577756  Black

我需要输出类似的东西

ID  changes column name Old_value   new_value
----------------------------------------------------------
111         City        Kerala      Delhi
111         Category    White       Red
113         City        Jammu       Pune 
113         Phone       987456      577756

但这不是动态的,我使用的是 oracle

select distinct 
  hist.ID, 
  'city' as Changed_Column, 
  hist.cityas Old_Value, 
  daily.cityas New_Value
from table A dly  daily 
inner join table b hist on daily.ID= hist.ID
  and daily.city <> hist.city

【问题讨论】:

  • 当列的类型不同时会发生什么?
  • 是的...列不同

标签: sql oracle


【解决方案1】:

使用UNPIVOT将每个表中的列转换为行,然后将两者连接起来:

Oracle 设置

CREATE TABLE TableA ( ID, Name, City, Phone, Category ) AS
SELECT 111, 'ABC', 'Delhi',  '123456', 'Red'   FROM DUAL UNION ALL
SELECT 112, 'BCD', 'Mumbai', '234987', 'Green' FROM DUAL UNION ALL
SELECT 113, 'CGU', 'PUNE',   '987456', 'Black' FROM DUAL;

CREATE TABLE TableB ( ID, City, Phone, Category ) AS
SELECT 111, 'Kerala', '123456', 'White' FROM DUAL UNION ALL
SELECT 113, 'Jammu',  '577756', 'Black' FROM DUAL

查询

SELECT a.id,
       a.column_name,
       a.old_value,
       b.new_value
FROM   (
         SELECT id, column_name, old_value
         FROM   TableA
         UNPIVOT ( old_value FOR column_name IN ( City, Phone, Category ) )
       ) a
       INNER JOIN
       (
         SELECT id, column_name, new_value
         FROM   TableB
         UNPIVOT ( new_value FOR column_name IN ( City, Phone, Category ) )
       ) b
       ON ( a.id = b.id AND a.column_name = b.column_name )
WHERE a.old_value <> b.new_value

输出

身份证 | COLUMN_NAME | OLD_VALUE | NEW_VALUE --: | :------------ | :-------- | :-------- 111 |城市 |德里 |喀拉拉邦 111 |类别 |红色 |白色的 113 |城市 |浦那 |查谟 113 |电话 | 987456 | 577756

db小提琴here

【讨论】:

  • @MTO 。 . .这假定所有值都是字符串。
  • 是的.. 谢谢,但我需要动态,因为我有 250 列
  • @GordonLinoff 这很容易解决 - 只需将所有列转换为相同的数据类型(即字符串)db<>fiddle
  • @kirtichoudhary 您不能在 SQL 查询中使用 dynamic PIVOTUNPIVOT。您需要有一组固定的列 - 为什么不在UNPIVOTIN 列表中列出所有 250 列?查询将处理它。
  • @kirtichoudhary “这不起作用”不是一个建设性的陈述。为什么它对您不起作用,发生了什么错误/问题?我给出的答案给出了您问题中minimal reproducible example 的预期输出;因此,如果您在将其应用于完整数据集时遇到问题,那么您需要查看问题中的示例与实际数据的不同之处并调试这些部分。如果您想要“其他方式”,那么您将不得不澄清您想要获得“其他方式”的是什么。
猜你喜欢
  • 2017-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-06
  • 1970-01-01
  • 2019-11-16
  • 2015-06-15
相关资源
最近更新 更多