在SQLite中,如何查询两个表中的更改值,并将匹配值清零
In SQLite, how do I query the changed values in two tables, and NULL out the matching values
如果我在两个不同的表中有两行,例如:
Table 姓名 - 旧
id
title
views
wx
How to clean a drill
30
np
Craziest Fails
400
zo
Eating Challenge
8
lf
JavaScript Tutorial
0
Table 姓名 - 新
id
title
views
wx
How to clean a drill
30
np
Craziest Fails
450
zo
This was a mistake
8
lf
Learning JavaScript
20
两个表的区别如下:
- 第 1 行 (id=wx):
title
和 views
没有改变。
- 第2行(id=np):
views
增加了,而title
不变
- 第3行(id=zo):
title
变了,views
不变。
- 第 4 行 (id=lf):
title
和 views
都已更改。
想要的结果
我想要一个 returns Table Name - New 的查询,但任何未从 [= 改变的值79=] 名称 - 旧 应该是 null
,而不是 id
。如果整行没有改变,则不应返回该行。
id
是不变的,不会改变。
查询结果
id
title
views
np
null
450
zo
This was a mistake
null
lf
Learning JavaScript
20
我得到的最接近的是
SELECT * FROM new EXCEPT SELECT * FROM old;
但这不会null
得出未更改的值。
如有任何帮助,将不胜感激。
我认为这是 NULLIF
函数的情况。来自 docs:
The nullif(X,Y) function returns its first argument if the arguments are different and NULL if the arguments are the same. The nullif(X,Y) function searches its arguments from left to right for an argument that defines a collating function and uses that collating function for all string comparisons. If neither argument to nullif() defines a collating function then the BINARY is used.
因此您可以在 id
上加入两个表并通过 NULLIF
传递每一列
SELECT
new.id
, NULLIF(new.title, old.title)
, NULLIF(new.views, old.views)
FROM
new
JOIN old ON new.id = old.id
;
加入表并检查对应的列是否不同:
SELECT o.id,
NULLIF(n.title, o.title) title,
NULLIF(n.views, o.views) views
FROM Old o INNER JOIN New n
ON n.id = o.id
WHERE n.title <> o.title OR n.views <> o.views;
如果列 title
和 views
可能包含空值,则使用 IS NOT
比较它们:
SELECT o.id,
NULLIF(n.title, o.title) title,
NULLIF(n.views, o.views) views
FROM Old o INNER JOIN New n
ON n.id = o.id
WHERE n.title IS NOT o.title OR n.views IS NOT o.views
参见demo。
如果我在两个不同的表中有两行,例如:
Table 姓名 - 旧
id | title | views |
---|---|---|
wx | How to clean a drill | 30 |
np | Craziest Fails | 400 |
zo | Eating Challenge | 8 |
lf | JavaScript Tutorial | 0 |
Table 姓名 - 新
id | title | views |
---|---|---|
wx | How to clean a drill | 30 |
np | Craziest Fails | 450 |
zo | This was a mistake | 8 |
lf | Learning JavaScript | 20 |
两个表的区别如下:
- 第 1 行 (id=wx):
title
和views
没有改变。 - 第2行(id=np):
views
增加了,而title
不变 - 第3行(id=zo):
title
变了,views
不变。 - 第 4 行 (id=lf):
title
和views
都已更改。
想要的结果
我想要一个 returns Table Name - New 的查询,但任何未从 [= 改变的值79=] 名称 - 旧 应该是 null
,而不是 id
。如果整行没有改变,则不应返回该行。
id
是不变的,不会改变。
查询结果
id | title | views |
---|---|---|
np | null |
450 |
zo | This was a mistake | null |
lf | Learning JavaScript | 20 |
我得到的最接近的是
SELECT * FROM new EXCEPT SELECT * FROM old;
但这不会null
得出未更改的值。
如有任何帮助,将不胜感激。
我认为这是 NULLIF
函数的情况。来自 docs:
The nullif(X,Y) function returns its first argument if the arguments are different and NULL if the arguments are the same. The nullif(X,Y) function searches its arguments from left to right for an argument that defines a collating function and uses that collating function for all string comparisons. If neither argument to nullif() defines a collating function then the BINARY is used.
因此您可以在 id
上加入两个表并通过 NULLIF
SELECT
new.id
, NULLIF(new.title, old.title)
, NULLIF(new.views, old.views)
FROM
new
JOIN old ON new.id = old.id
;
加入表并检查对应的列是否不同:
SELECT o.id,
NULLIF(n.title, o.title) title,
NULLIF(n.views, o.views) views
FROM Old o INNER JOIN New n
ON n.id = o.id
WHERE n.title <> o.title OR n.views <> o.views;
如果列 title
和 views
可能包含空值,则使用 IS NOT
比较它们:
SELECT o.id,
NULLIF(n.title, o.title) title,
NULLIF(n.views, o.views) views
FROM Old o INNER JOIN New n
ON n.id = o.id
WHERE n.title IS NOT o.title OR n.views IS NOT o.views
参见demo。