根据唯一的多列结果集查询 table
Query table based on unique multiple column results set
有一个 users
table 和一个 matches
table。一场比赛由 userId1
和 userId2
(以及它自己的 id
)组成。我正在尝试 return 所有与某个用户 ID 不匹配的用户。
因此,如果您的用户 ID 为 1
、2
、3
、4
、5
并且与 2|5
相匹配, 2|3
, 1|2
那么我希望在搜索 ID 为 1
的用户时返回 ID 为 3
、 4
和 5
的用户。我不期望 2
因为与 1
匹配,我不期望 1
因为它是用户本身。我确实期望 3
,因为匹配与 1
不匹配,5
也是如此。我也期待 4
因为在比赛 table.
中找不到它
我一直在寻找如何解决这个问题,我觉得我需要使用 EXIST
或 IN
,但我认为我遇到了语法错误,因为数量我比较的结果不一样?
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.
有一个 users
table 和一个 matches
table。一场比赛由 userId1
和 userId2
(以及它自己的 id
)组成。我正在尝试 return 所有与某个用户 ID 不匹配的用户。
因此,如果您的用户 ID 为 1
、2
、3
、4
、5
并且与 2|5
相匹配, 2|3
, 1|2
那么我希望在搜索 ID 为 1
的用户时返回 ID 为 3
、 4
和 5
的用户。我不期望 2
因为与 1
匹配,我不期望 1
因为它是用户本身。我确实期望 3
,因为匹配与 1
不匹配,5
也是如此。我也期待 4
因为在比赛 table.
我一直在寻找如何解决这个问题,我觉得我需要使用 EXIST
或 IN
,但我认为我遇到了语法错误,因为数量我比较的结果不一样?
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.