[英]Oracle SQL - Compare key and values in the same table
(reverting edit) I have a table that houses keys and values of configuration for different customer. (还原编辑)我有一个表,其中包含不同客户的键和配置值。
CustomerID Key Value
C1 AskPhoneNo TRUE
C1 Website C1Website.com
C1 Report TRUE
C2 AskPhoneNo TRUE
C2 Report FALSE
C2 AskAddress TRUE
I need to compare the data between C1 and C2 and Show diffs like this 我需要比较C1和C2之间的数据并像这样显示差异
C1 AskPhoneNo TRUE C2 AskPhoneNo TRUE
C1 Website C1Website.com C2 - -
C1 Report TRUE C2 Report False
C1 AskAddress - C2 AskAddress
What query can be used to get this result? 可以使用什么查询来获得此结果?
There are two problems with your required output. 所需的输出有两个问题。 First, there's no point in the constant columns (with values C1 and C2 respectively), and there's no reason to repeat the key names.
首先,常量列中没有意义(分别具有值C1和C2),也没有理由重复键名。 Second, your output seems to show ALL the rows, not just the "differences".
其次,您的输出似乎显示所有行,而不仅仅是“差异”。 If you need to show ALL the rows (whether the values are the same or different), just remove the
where
clause below. 如果需要显示所有行(值是相同还是不同),只需删除下面的
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
you can use full outer join + nvl
您可以使用
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"
\nCUSTOMERID |客户| KEY |
KEY | VALUE |
值| CUSTOMERID |
客户| KEY |
KEY | VALUE
值 \n:--------- |
:--------- | :--------- |
:--------- | :------------ |
:------------ | :--------- |
:--------- | :--------- |
:--------- | :---------
:---------\nC1 |
C1 | AskPhoneNo |
AskPhoneNo | TRUE |
TRUE | C2 |
C2 | AskPhoneNo |
AskPhoneNo | AskPhoneNo
问电话\nC1 |
C1 | Report |
报告| TRUE |
TRUE | C2 |
C2 | Report |
报告| Report
报告 \nC1 |
C1 | AskAddress |
AskAddress | null |
空 | C2 |
C2 | AskAddress |
AskAddress | null
空值 \nC1 |
C1 | Website |
网站| C1Website.com |
C1Website.com | C2 |
C2 | Website |
网站| Website
网站 \n
Here is a version with parameterized Customer IDs 这是带有参数化客户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
to test I used 测试我用
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
Are you going to compare data only between 2 customers? 您是否只比较两个客户之间的数据?
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;
I hope, this is self-explanatory. 希望这是不言而喻的。 But this particular SQL will work only if you have cust1 and cust2 values.
但是,仅当您具有cust1和cust2值时,此特定的SQL才有效。 If some of them missing, we need use left and right joins, or a
FULL JOIN
如果其中一些缺少,我们需要使用左右联接,或
FULL JOIN
In order to compare all customers with each other, first join customer to customer. 为了比较所有客户,首先将客户加入客户。 Cross join all keys.
交叉联接所有键。 Then outer join the data:
然后外部加入数据:
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;
(I suppose you have a customers table, so you can remove the WITH
clause.) (我想您有一个customers表,因此您可以删除
WITH
子句。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.