首页 > 解决方案 > 基于唯一多列结果集的查询表

问题描述

有一张users桌子和一张matches桌子。匹配由一个userId1and userId2(和它自己的id)组成。我正在尝试返回与某个 userId 不匹配的所有用户。

因此,如果您的用户的 id1为 , 2, 3,并且与 , 匹配4,那么我希望在搜索具有 id 的用户时返回具有 id 的用户。我不期望,因为有匹配,我不期望,因为它是用户本身。我确实期待,因为比赛不是 with ,同样适用于。我也期待,因为它没有在匹配表中找到。52|52|31|234512113154

我一直在寻找如何解决这个问题,我觉得我需要使用EXISTor 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)

请在下面找到示例数据,以及相同的小提琴

这将是我要复制的设置:

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)

标签: mysqljoinleft-join

解决方案


您可以使用自连接来执行此操作,该连接Users将返回 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。
请参阅演示


推荐阅读