我一直在为一个特定的问题做一些搜索,但我找不到这个特别的问题
我在SQL中有一个非常不寻常的任务:
我有两个表,比如A和B,它们具有完全相同的列名,具有以下形式:
id | column_1 | ... | column_n
两个表具有相同的行数,具有相同的id,但对于给定的id,表A和B中的行有可能在一个或多个其他列中不同。
我已经有一个查询返回表A中的所有行,其中表B中的相应行不相同,但我需要的是一个返回表单内容的查询:
id | differing_column
----------------------
1 | column_1
3 | column_6
意味着ID为'1'的行在表A和B中具有不同的'column_1'值,而ID为'3'的行在表A和B中具有不同的'column_6'值。
这完全可以实现吗?我想它可能需要某种枢轴才能将列名称作为值,但我可能错了。任何帮助/建议非常感谢。
答案 0 :(得分:0)
您可以使用unpivot
执行此操作 - 假设列中的值属于同一类型。
如果您的数据不是太大,我建议您使用一堆union all
语句:
select a.id, 'Col1' as column
from a join b on a.id = b.id
where a.col1 <> b.col1 or a.col1 is null and b.col1 is not null or a.col1 is not null and b.col1 is null
union all
select a.id, 'Col2' as column
from a join b on a.id = b.id
where a.col2 <> b.col2 or a.col2 is null and b.col2 is not null or a.col2 is not null and b.col2 is null
. . .
这可以防止潜在的类型转换问题。
如果你不介意将结果放在一行,你可以这样做:
select a.id,
(case when a.col1 <> b.col1 or a.col1 is null and b.col1 is not null or a.col1 is not null and b.col1 is null
then 'Col1;'
else ''
end) +
(case when a.col2 <> b.col2 or a.col2 is null and b.col2 is not null or a.col2 is not null and b.col2 is null
then 'Col2;'
else ''
end) +
. . .
from a join b on a.id = b.id;
答案 1 :(得分:0)
是的,您可以使用以下查询执行此操作:
WITH Diffs (Id, Col) AS (
SELECT
a.Id,
CASE
WHEN a.Col1 <> b.Col1 THEN 'Col1'
WHEN a.Col2 <> b.Col2 THEN 'Col2'
-- ...and so on
ELSE NULL
END as Col
FROM TableOne a
JOIN TableTwo b ON a.Id=b.Id
)
SELECT Id, Col
WHERE Col IS NOT NULL
请注意,上述查询不会返回所有具有差异的列,而只返回它将要查找的第一个列。
答案 2 :(得分:0)
如果您的列类型相同,则有一个灵巧的方法:
SELECT id,col
FROM (SELECT * FROM A UNION ALL SELECT * FROM B) t1
UNPIVOT (value for col in (column_1,column_2,column_3,column_4)) t2
GROUP BY id,col
HAVING COUNT(DISTINCT value) > 1
如果您需要将NULL作为唯一值处理,则使用HAVING COUNT(DISTINCT ISNULL(value,X)) > 1
,其中X是数据中未出现的值