我知道MariaDB和MySQL不支持EXCEPT。 我想找到这样的替代方案:
SELECT * FROM table
EXCEPT
SELECT * FROM backup_table
表和backup_table具有相同的架构。
我见过的所有帖子都建议我使用“WHERE列IN(...)”来比较单个列。 我的问题是我需要比较每个表的两个表之间的所有列。我希望将此作为过程或函数循环遍历所有表,寻找数据库中的任何更改。基本上,我想找出所有已更新或插入所有表中的记录。
答案 0 :(得分:2)
如果我遇到这个任务,我会使用反连接模式。这是一个外部联接,用于返回当前表中的所有行,以及"匹配"备份表中的行。然后在WHERE子句中,我们排除所有具有完全匹配的行。返回不匹配的行。
SELECT t.*
FROM mytable t
LEFT
JOIN backup_mytable s
ON s.id <=> t.id
AND s.col_two <=> t.col_two
AND s.col_three <=> t.col_three
AND ...
WHERE s.id IS NULL
这假设列id
保证为非NULL。 PRIMARY KEY列(或者是表的PRIMARY KEY的任何列,或任何具有NOT NULL约束的列都可以服务。)
此查询仅返回与备份表中的行不匹配的行。它没有表明它的行是否存在,或者列的值是否发生了变化。
要在原始表中获取与备份表中的行不匹配的行,只需交换表名。
对于将所有列定义为NOT NULL的表的特殊情况,我们可以在连接谓词上使用快捷方式。
FROM mytable t
NATURAL
LEFT
JOIN backup_mytable s
WHERE s.id IS NULL
这等同于LEFT JOIN,其中所有列的USING子句在两个表中都被命名为相同。
FROM mytable t
LEFT
JOIN backup_mytable s
USING (id, col_two, col_three, ...)
WHERE s.id IS NULL
这等同于在每列上指定相等比较(如果两个表具有相同的列)
FROM mytable t
LEFT
JOIN backup_mytable s
ON s.id = t.id
AND s.col_two = t.col_two
AND s.col_three = t.col_three
任何列中出现任何NULL值都会使用相等比较,并返回NULL。
这就是为什么第一个查询使用空安全比较<=>
(太空飞船)运算符的原因。 NULL <=> NULL
将返回TRUE,其中NULL = NULL
将返回NULL。
对于第一个查询模式,我会使用SQL来帮助我生成所需的SQL,而不是单调乏味地输入每列的所有比较。
SELECT CONCAT(' AND s.`',c.column_name,'` <=> t.`',c.column_name,'`') AS `-- stmt`
FROM information_schema.columns c
WHERE c.table_schema = 'mydatabase'
AND c.table_name = 'mytable'
ORDER BY c.ordinal_position
我将获取该查询返回的行,并将其粘贴到
中SELECT t.*
FROM ... t
JOIN ... s
ON 1=1
-- paste here --
WHERE s.id IS NULL
ORDER BY t.id
如果我需要仅在id
列上匹配的查询,并且需要识别哪些列已更改,我将在SELECT列表中使用表达式。例如:
SELECT s.`id` <=> t.`id` AS `match_id`
, s.`col_one` <=> t.`col_one` AS `match_col_one`
, s.`col_three` <=> t.`col_three` AS `match_col_three`
FROM mytable t
JOIN backup_mytable s
ON s.id = t.id
HAVING NOT match_col_one
这里引用HAVING
子句中SELECT列表中的列别名,以排除具有相同值col_one
的行;返回col_one
不同的行。
同样,我会对info_schema.columns使用SQL来帮助加快查询编写过程。
答案 1 :(得分:1)
我对MySQL或MariaDB没有多少经验,但我发现这是对可能对你有用的另一个问题的答案。
SELECT *
FROM match m
WHERE NOT EXISTS
(
SELECT 1
FROM email e
WHERE e.id = m.id
)
来自以下帖子的Quassnoi: MySQL SELECT x FROM a WHERE NOT IN ( SELECT x FROM b ) - Unexpected result
答案 2 :(得分:0)
从version 10.3.0开始,MariaDB添加了对缺少的集合操作的支持,包括但不限于EXCEPT。
computed: {
searchTrigger () {
if (this.search.length >= 3) {
return this.search
}
}
}