我有两个表,tmp1和tmp2:
tmp1:
+----+------+---------+---------+
| id | name | add1 | add2 |
+----+------+---------+---------+
| 1 | NULL | NULL | NULL |
| 2 | mum | rajpur | rajpur1 |
| 3 | mum1 | rajpur1 | rajpur2 |
| 4 | mum3 | rajpur3 | rajpur4 |
| 5 | mum4 | rajpur4 | rajpur5 |
+----+------+---------+---------+
tmp2:
+----+------+---------+---------+
| id | name | add1 | add2 |
+----+------+---------+---------+
| 1 | NULL | NULL | NULL |
| 2 | mum | rajpur | rajpur1 |
| 3 | mum1 | rajpur6 | rajpur7 |
| 4 | mum3 | rajpur3 | rajpur8 |
| 5 | mum4 | rajpur4 | rajpur5 |
+----+------+---------+---------+
在这里我应用了一个SQL查询,但是,与第二个表相比,空值属性的ID或不匹配值属性的ID将从第一个表中检索:
SELECT a.id
FROM tmp1 a
INNER JOIN tmp2 b
ON a.id = b.id
AND ( ( a.name IS NULL
OR a.add1 IS NULL
OR a.add2 IS NULL )
OR ( a.name != b.name
OR a.add1 != b.add1
OR a.add2 != b.add2 ) );
上面的sql查询给我下面的结果:
+----+
| id |
+----+
| 1 |
| 3 |
| 4 |
+----+
这很好,使用上面的查询,我得到了想要的结果。
现在,我想检索与第二张表相比在第一张表中出现更改的那些列名,或者在第一张表中保留列名的空值,我希望我的结果如下所示:
+----+-----------------+
| id | Changed Columns |
+----+-----------------+
| 1 | name,add1,add2 |
| 3 | add1,add2 |
| 4 | add2 |
+----+-----------------+
答案 0 :(得分:0)
您可以将Concat_ws()
函数与使用CASE .. WHEN
的条件检查一起使用。关于Concat_Ws
函数的好处是,如果参数列表中存在NULL
值,它将忽略它(而不是将其串联)。
因此,我们可以使用CASE .. WHEN
语句分别检查列,如果它们符合我们的条件,则返回列名(作为字符串),否则返回null
。
SELECT
a.id,
CONCAT_WS(',',
CASE WHEN a.name IS NULL OR a.name <> b.name THEN 'name' ELSE NULL END,
CASE WHEN a.add1 IS NULL OR a.add1 <> b.add1 THEN 'add1' ELSE NULL END,
CASE WHEN a.add2 IS NULL OR a.add2 <> b.add2 THEN 'add2' ELSE NULL END
) AS Changed_Columns
FROM tmp1 a
INNER JOIN tmp2 b
ON a.id = b.id
AND ( ( a.name IS NULL
OR a.add1 IS NULL
OR a.add2 IS NULL )
OR ( a.name <> b.name
OR a.add1 <> b.add1
OR a.add2 <> b.add2 ) );
结果
| id | Changed_Columns |
| --- | --------------- |
| 1 | name,add1,add2 |
| 3 | add1,add2 |
| 4 | add2 |
答案 1 :(得分:0)
如果列名不相同,则将它们串联起来:
users
请参见demo。
结果:
select a.id,
trim(trailing ',' from concat(
case when a.name = b.name then '' else 'name,' end,
case when a.add1 = b.add1 then '' else 'add1,' end,
case when a.add2 = b.add2 then '' else 'add2' end
)) `Changed Columns`
from tmp1 a inner join tmp2 b
on a.id=b.id and (
(a.name is NULL or a.add1 is NULL or a.add2 is NULL)
or
(a.name!=b.name or a.add1!=b.add1 or a.add2!=b.add2)
);
答案 2 :(得分:0)
另一种方法:
select id, group_concat(f order by f) as `Changed Columns` from (
select tmp1.id, 'name' as f from tmp1 join tmp2 on tmp1.id = tmp2.id and (tmp1.name is null or tmp1.name <> tmp2.name)
union
select tmp1.id, 'add1' as f from tmp1 join tmp2 on tmp1.id = tmp2.id and (tmp1.add1 is null or tmp1.add1 <> tmp2.add1)
union
select tmp1.id, 'add2' as f from tmp1 join tmp2 on tmp1.id = tmp2.id and (tmp1.add2 is null or tmp1.add2 <> tmp2.add2)
) sq
group by id
order by id
;