繁体   English   中英

Oracle SQL-比较同一表中的键和值

[英]Oracle SQL - Compare key and values in the same table

(还原编辑)我有一个表,其中包含不同客户的键和配置值。

CustomerID    Key              Value
C1            AskPhoneNo       TRUE
C1            Website          C1Website.com
C1            Report           TRUE 
C2            AskPhoneNo       TRUE
C2            Report           FALSE
C2            AskAddress       TRUE

我需要比较C1和C2之间的数据并像这样显示差异

C1            AskPhoneNo       TRUE                C2    AskPhoneNo       TRUE
C1            Website          C1Website.com       C2      -               -
C1            Report           TRUE                C2    Report          False
C1            AskAddress       -                   C2    AskAddress   

可以使用什么查询来获得此结果?

所需的输出有两个问题。 首先,常量列中没有意义(分别具有值C1和C2),也没有理由重复键名。 其次,您的输出似乎显示所有行,而不仅仅是“差异”。 如果需要显示所有行(值是相同还是不同),只需删除下面的where子句。

with
  test_data(customer_id, key, value) as (
    select 'C1', 'AskPhoneNo', 'TRUE'          from dual union all
    select 'C1', 'Website'   , 'C1Website.com' from dual union all
    select 'C1', 'Report'    , 'TRUE'          from dual union all
    select 'C2', 'AskPhoneNo', 'TRUE'          from dual union all
    select 'C2', 'Report'    , 'FALSE'         from dual union all
    select 'C2', 'AskAddress', 'TRUE'          from dual union all
    select 'C3', 'AskAddress', 'FALSE'         from dual union all
    select 'C3', 'Report'    , 'TRUE'          from dual union all
    select 'C3', 'Website'   , 'C3web.edu'     from dual
  )
-- End of simulated inputs (for testing only, not part of the solution!)
select key, c1_value, c2_value
from   test_data
pivot  (max(value) for customer_id in ('C1' as c1_value, 'C2' as c2_value))
where  decode(c1_value, c2_value, 0, 1) = 1  -- If needed
order  by key                                -- If needed
;

KEY        C1_VALUE      C2_VALUE     
---------- ------------- -------------
AskAddress               TRUE         
Report     TRUE          FALSE        
Website    C1Website.com              

您可以使用full outer join + nvl

CREATE TABLE T
    ("CustomerID" varchar2(2), "Key" varchar2(10), "Value" varchar2(13));


INSERT ALL 
    INTO T ("CustomerID", "Key", "Value")
         VALUES ('C1', 'AskPhoneNo', 'TRUE')
    INTO T ("CustomerID", "Key", "Value")
         VALUES ('C1', 'Website', 'C1Website.com')
    INTO T ("CustomerID", "Key", "Value")
         VALUES ('C1', 'Report', 'TRUE')
    INTO T ("CustomerID", "Key", "Value")
         VALUES ('C2', 'AskPhoneNo', 'TRUE')
    INTO T ("CustomerID", "Key", "Value")
         VALUES ('C2', 'Report', 'FALSE')
    INTO T ("CustomerID", "Key", "Value")
         VALUES ('C2', 'AskAddress', 'TRUE')
SELECT * FROM dual;



select 
    nvl(T1."CustomerID",'C1') as CustomerID,
    nvl(T1."Key",T2."Key") as Key,
    T1."Value" as Value,
    nvl(T2."CustomerID",'C2') as CustomerID,
    nvl(T2."Key",T1."Key") as Key,
    nvl(T1."Key",null) as Value
 from (
     select  * from T where "CustomerID" = 'C1'
 ) T1
 full outer join (
     select  * from T where "CustomerID" = 'C2'
 ) T2
 on T1."Key" = T2."Key"
\n 客户|  KEY |  值|  客户|  KEY |       \n :--------- |  :--------- |  :------------ |  :--------- |  :--------- |  :---------\n C1 |  AskPhoneNo |  TRUE |  C2 |  AskPhoneNo |  问电话\n C1 |  报告|  TRUE |  C2 |  报告|  报告    \n C1 |  AskAddress |   |  C2 |  AskAddress |  空值      \n C1 |  网站|  C1Website.com |  C2 |  网站|  网站   \n

db <> 在这里拨弄

这是带有参数化客户ID的版本

with 
 Cust1 as (select 'C1' as C_id from DUAL)
,Cust2 as (select 'C2' as C_id from DUAL)
select (select C_id from Cust1) ID1,
       coalesce(t1.K, t2.K) Key1,
       t1.V as Value1,
       (select C_id from Cust2) ID2,
       coalesce(t2.K, t1.K) Key2,
       t2.V as Value2
 from 
 (select * from t where id = (select C_id from Cust1)) t1
   full outer join (select * from t where id = (select C_id from Cust2)) t2 
   on t1.k = t2.k

测试我用

with 
 Cust1 as (select 'C1' as C_id from DUAL)
,Cust2 as (select 'C2' as C_id from DUAL)
,t as (
select 'C1' ID, 'AskPhoneNo' K, 'TRUE' V union
select 'C1', 'Website', 'C1Website.com' union
select 'C1', 'Report',  'TRUE' union
select 'C2', 'AskPhoneNo', 'TRUE' union
select 'C2', 'Report', 'FALSE' union
select 'C2', 'AskAddress', 'TRUE')
select (select C_id from Cust1) ID1,
       coalesce(t1.K, t2.K) Key1,
       t1.V as Value1,
       (select C_id from Cust2) ID2,
       coalesce(t2.K, t1.K) Key2,
       t2.V as Value2
 from 
 (select * from t where id = (select C_id from Cust1)) t1
   full outer join (select * from t where id = (select C_id from Cust2)) t2 
   on t1.k = t2.k

您是否只比较两个客户之间的数据?

Select 
    cust1, key1, val1,
    cust2, key2, val2      
from
    (select CustomerID cust1, key key1, value val1
     from myTable
     where CustomerID = 1) c1 inner join 
    (select CustomerID cust2, key key2, value val2
     from myTable
     where CustomerID = 2) c2 on 
        c1.key1 = c2.key2;

希望这是不言而喻的。 但是,仅当您具有cust1和cust2值时,此特定的SQL才有效。 如果其中一些缺少,我们需要使用左右联接,或FULL JOIN

为了比较所有客户,首先将客户加入客户。 交叉联接所有键。 然后外部加入数据:

with customers as (select distinct customerid from mytable)
select
  k.key,
  c1.customerid as customerid1, m1.value as value1,
  c2.customerid as customerid2, m2.value as value2
from customers c1
join customers c2 on c2.customerid > c1.customerid
cross join (select distinct key from mytable) k
left join mytable m1 on m1.customerid = c1.customerid and m1.key = k.key
left join mytable m2 on m2.customerid = c2.customerid and m2.key = k.key
order by customerid1, customerid2, k.key;

(我想您有一个customers表,因此您可以删除WITH子句。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM