我正在检查一个表的 2 个外部 ID 是否等于同一个表的另一个表中的 2 个外键,但我不关心 ID 的顺序,只关心它们具有相同的值。
即
SELECT (1, 2, 3) = (1, 2, 3);
> 1
SELECT (1, 2, 3) = (2, 1, 3);
> 0
我想要一种方法让 (1,2,3)
匹配 (2,1,3)
以及 (1,3 ,2)
和 (2,3,1)
。
不幸的是,事实证明搜索这方面的信息很困难,大多数建议是“MySQL 中不存在列表”,搜索排序或无序检查会导致各种不相关的 SQL 调用。
fiddle :https://www.db-fiddle.com/f/eqz27tR9uDMQriDhkwBo2a/0
我特意在表中放了一个event
,参与者的顺序与not_event
中的参与者不同,就是那个join,
SELECT * FROM event
JOIN not_event ON (
(event.participant_1_id, event.participant_2_id) =
(not_event.participant_1_id, not_event.participant_2_id));
这就是问题所在。我不在乎 participant_1_id
和 participant_2_id
在任一表中的顺序,只要它们是相同的 2。
来自 fiddle 的其余代码,
CREATE TABLE `participant` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`key` varchar(15) NOT NULL,
PRIMARY KEY (`id`));
CREATE TABLE `event` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`participant_1_id` int(11) NOT NULL,
`participant_2_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `event_ibfk_1` FOREIGN KEY (`participant_1_id`) REFERENCES `participant` (`id`),
CONSTRAINT `event_ibfk_2` FOREIGN KEY (`participant_2_id`) REFERENCES `participant` (`id`)
);
CREATE TABLE `not_event` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`participant_1_id` int(11) NOT NULL,
`participant_2_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `not_event_ibfk_1` FOREIGN KEY (`participant_1_id`) REFERENCES `participant` (`id`),
CONSTRAINT `not_event_ibfk_2` FOREIGN KEY (`participant_2_id`) REFERENCES `participant` (`id`)
);
INSERT INTO `participant` VALUES (1, 'Team1');
INSERT INTO `participant` VALUES (2, 'Team2');
INSERT INTO `event` VALUES (NULL, 1, 2);
INSERT INTO `not_event` VALUES (NULL, 2, 1);
SELECT (1, 2, 3) = (1, 2, 3);
SELECT (1, 2, 3) = (2, 1, 3);
SELECT * FROM event
JOIN not_event ON (
(event.participant_1_id, event.participant_2_id) =
(not_event.participant_1_id, not_event.participant_2_id));
SELECT * FROM event
JOIN not_event ON (
(event.participant_1_id, event.participant_2_id) =
(not_event.participant_2_id, not_event.participant_1_id));
最佳答案
几个选项,没有一个我真的很满意,
对于二元联接,只有 2 个字段,使用 LEAST
和 GREATEST
可行,但在超过 2 个字段时,它不起作用,
SELECT * FROM event
JOIN not_event ON (
LEAST(event.participant_1_id, event.participant_2_id) =
LEAST(not_event.participant_1_id, not_event.participant_2_id)
AND
GREATEST(event.participant_1_id, event.participant_2_id) =
GREATEST(not_event.participant_1_id, not_event.participant_2_id));
在那之后,似乎有一个非常低效的 LENGTH
检查,有多个 REPLACE
和 CONCAT_WS
,
SELECT * FROM event
JOIN not_event ON (
1 = LENGTH(REPLACE(REPLACE(
CONCAT_WS(
',', event.participant_1_id, event.participant_2_id),
not_event.participant_1_id, ''), not_event.participant_2_id, ''))
);
但是这个很烂,而且不可靠,因为“1”会用“”代替“11”,“2”会用“”代替“222”,等等。
更新的 fiddle (使用这些解决方案):https://www.db-fiddle.com/f/eqz27tR9uDMQriDhkwBo2a/1
关于mysql - 在 MySQL 中检查一组值是否等于另一组的值;不在乎顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53016323/