我正在检查一个表的2个外来ID是否等于同一张表中另一个表中的2个外键,但是我不在乎这些ID的顺序,只是它们具有相同的值。 / p>
即
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调用。
提琴:https://www.db-fiddle.com/f/eqz27tR9uDMQriDhkwBo2a/0
我故意将event
放在表中,参与者的顺序与not_event
中的参与者的顺序不同,那就是联接
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。
从小提琴中提取代码,
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));
答案 0 :(得分:1)
一些选择,我真的不满意,
对于只有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”替换为“”,依此类推。
更新的小提琴(使用这些解决方案):https://www.db-fiddle.com/f/eqz27tR9uDMQriDhkwBo2a/1
答案 1 :(得分:0)
我发现,您可以通过3种不同的方法实现这一目标。 1是查询event
和not_event
表,并将participant
表连接两次,将它们分组在一起,并运行GROUP BY
和HAVING
比较{{1 }},
GROUP_CONCAT
或者通过在您有兴趣加入的字段上运行两个SELECT event.*, not_event.*
FROM event
JOIN participant p1 ON p1.id IN (event.participant_1_id, event.participant_2_id),
not_event
JOIN participant p2 ON p2.id IN (not_event.participant_1_id, not_event.participant_2_id)
GROUP BY event.id, not_event.id
HAVING
GROUP_CONCAT(p1.key ORDER BY p1.key) =
GROUP_CONCAT(p2.key ORDER BY p2.key)
子查询,然后再将其加入,
GROUP_CONCAT
然后是超级“直接”或手动方式,
SELECT *
FROM (
SELECT GROUP_CONCAT(participant.id ORDER BY participant.id) `key`, event.*
FROM event
JOIN participant ON (participant.id IN (event.participant_1_id, event.participant_2_id))
GROUP BY event.id) _event
JOIN (
SELECT GROUP_CONCAT(participant.id ORDER BY participant.id) `key`, not_event.*
FROM not_event
JOIN participant ON (participant.id IN (not_event.participant_1_id, not_event.participant_2_id))
GROUP BY not_event.id) _not_event
ON _event.key = _not_event.key;
这些都可以根据需要正确加入。
更新的小提琴: https://www.db-fiddle.com/f/eqz27tR9uDMQriDhkwBo2a/5
对于这两种解决方案, SELECT event.*, not_event.*
FROM event, not_event
WHERE
event.participant_1_id IN (not_event.participant_1_id, not_event.participant_2_id) AND
event.participant_2_id IN (not_event.participant_1_id, not_event.participant_2_id) AND
not_event.participant_1_id IN (event.participant_1_id, event.participant_2_id) AND
not_event.participant_2_id IN (event.participant_1_id, event.participant_2_id)
可以正确地与Event(1, 2)
联接,并且没有其他任何选择,而NotEvent(2, 1)
可以正确地与Event(2, 3)
联接,没有其他选择。
我的还是的认为这是疯狂的,你必须参加这样的表,这样,而不是仅仅比较直接在表内的键,但这些工作,这种或那种方式。< / p>