根据唯一的多列结果集查询 table

Query table based on unique multiple column results set

有一个 users table 和一个 matches table。一场比赛由 userId1userId2(以及它自己的 id)组成。我正在尝试 return 所有与某个用户 ID 不匹配的用户。

因此,如果您的用户 ID 为 12345 并且与 2|5 相匹配, 2|3, 1|2 那么我希望在搜索 ID 为 1 的用户时返回 ID 为 345 的用户。我不期望 2 因为与 1 匹配,我不期望 1 因为它是用户本身。我确实期望 3,因为匹配与 1 不匹配,5 也是如此。我也期待 4 因为在比赛 table.

中找不到它

我一直在寻找如何解决这个问题,我觉得我需要使用 EXISTIN,但我认为我遇到了语法错误,因为数量我比较的结果不一样?

select * from Users u
where not exist (select userId1 from Matches m where u.id = m.userId1) and
where not exist (select userId2 from Matches m where u.id = m.userId2)

请在下面找到示例数据,fiddle 相同。

这将是我要重现的设置:

CREATE TABLE `Users` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(256) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
  `createdAt` datetime NOT NULL,
  `updatedAt` datetime NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `users_id` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=257 DEFAULT CHARSET=utf8mb3 COLLATE=utf8_unicode_ci;

INSERT INTO `Users` (`id`, `name`, `createdAt`, `updatedAt`)
VALUES
    (1, 'Maria', '2021-07-11 00:51:36', '2021-07-11 18:09:58');

INSERT INTO `Users` (`id`, `name`, `createdAt`, `updatedAt`)
VALUES
    (2, 'Peter', '2021-07-11 00:51:36', '2021-07-11 18:09:58');
    
    INSERT INTO `Users` (`id`, `name`, `createdAt`, `updatedAt`)
VALUES
    (3, 'Sonya', '2021-07-11 00:51:36', '2021-07-11 18:09:58');
    
    INSERT INTO `Users` (`id`, `name`, `createdAt`, `updatedAt`)
VALUES
    (4, 'Frank', '2021-07-11 00:51:36', '2021-07-11 18:09:58');
    
    INSERT INTO `Users` (`id`, `name`, `createdAt`, `updatedAt`)
VALUES
    (5, 'Johnny', '2021-07-11 00:51:36', '2021-07-11 18:09:58');
    
    
    CREATE TABLE `Matches` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `userId1` int DEFAULT NULL,
  `userId2` int DEFAULT NULL,
  `createdAt` datetime NOT NULL,
  `updatedAt` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb3 COLLATE=utf8_unicode_ci;

INSERT INTO `Matches` (`id`, `userId1`, `userId2`, `createdAt`, `updatedAt`)
VALUES
    (1, 2, 5, '2021-07-12 21:57:31', '2021-07-12 21:57:31');

INSERT INTO `Matches` (`id`, `userId1`, `userId2`, `createdAt`, `updatedAt`)
VALUES
    (2, 2, 3, '2021-07-12 21:57:31', '2021-07-12 21:57:31');

INSERT INTO `Matches` (`id`, `userId1`, `userId2`, `createdAt`, `updatedAt`)
VALUES
    (3, 1, 2, '2021-07-12 21:57:31', '2021-07-12 21:57:31');
    
    
    select * from Users u
where not exist (select userId1 from Matches m where u.id = m.userId1) and
where not exist (select userId2 from Matches m where u.id = m.userId2)

您可以使用 Users 的自联接来完成此操作,这将 return 2 个用户的所有可能组合,然后左联接到 Matches 并过滤掉匹配的行:

SELECT u1.*
FROM `Users` u1 
INNER JOIN `Users` u2 ON u1.id <> u2.id
LEFT JOIN `Matches` m ON (m.userId1, m.userId2) IN ((u1.id, u2.id), (u2.id, u1.id))
WHERE m.id IS NULL AND u2.id = ?

? 更改为您要搜索的用户 ID。
参见 demo.