问题描述
我有 tableA 和 tableB,我在查询下面运行以获取计数大于 1 的 url
select
group_concat(institution_user_id),url
from
tableA as s
join tableB as i
on s.jove_institution_id = i.institutionid
group by
url
having
count(*) > 1;
在这里我得到多个用户 ID 的 url 大于 1。但是我需要那些在 tableC 中并且与 tableA institution_user_id 列与 tableC userid 列。是否可以使用 tablec 创建单个查询以获取用户 ID 的电子邮件地址。
我尝试了以下查询,但没有提供预期的结果。
select (select email from tablecwhere userid in (group_concat(institution_user_id))),count(*) as c from tableA as s join tableB as i on i.institutionid = s.jove_institution_id group by shibboleth_Metadata_url having c > 1;
这里我正在获取电子邮件 ID 列表。但我需要用户的电子邮件 ID。例如,如果 url www.google.com 有 2 个用户 ID,那么我需要查询我需要 tablec 中存在的该 url 的两个用户 ID 的电子邮件地址
CREATE TABLE tableA(
id int(11) NOT NULL AUTO_INCREMENT,url varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL,jove_institution_id int(11) NOT NULL,institution_user_id int(11) DEFAULT NULL,PRIMARY KEY (id)
) ;
CREATE TABLE tableB (
InstitutionID int(11) NOT NULL AUTO_INCREMENT,Name varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL,Approved tinyint(1) NOT NULL DEFAULT '0',DateAdded datetime DEFAULT CURRENT_TIMESTAMP,IsAcademic tinyint(1) DEFAULT NULL,PRIMARY KEY (InstitutionID)
);
CREATE TABLE tableC(
EmailID int(11) NOT NULL AUTO_INCREMENT,UserID int(11) NOT NULL,email varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,Verified tinyint(1) DEFAULT NULL,OptIn tinyint(1) DEFAULT NULL,lastverified datetime DEFAULT NULL,PRIMARY KEY (EmailID)
);
期望的输出
样本数据
INSERT INTO tableA VALUES (1,'xyz.com',23,111);
INSERT INTO tableA VALUES (2,222);
INSERT INTO tableA VALUES (3,'pqr.com',24,111);
INSERT INTO tableB VALUES (23,'Baylor Health Sciences Library',1,NULL,NULL);
INSERT INTO tableB VALUES (24,'Macquarie University',NULL);
INSERT INTO tableC VALUES (1234,111,'abc@gmail.com','2018-03-14 13:21:04');
INSERT INTO tableC VALUES (4235,222,'def@gmail.com','2018-03-14 13:22:11');
INSERT INTO tableC VALUES (4567,333,'stu@gmail.com','2018-03-14 13:30:23');
这里的 url 值 xyz.com 有 2 个用户 ID,对于用户 ID,我们需要从 tableC 获取电子邮件 ID。您可以忽略 tableB 因为它仅用于比较。
institution_user_id from tableA 与 tableC 中的 userid 的关系。 来自 tableB 的 InstitutionID 与来自 tableA 的 jove_institution_id。
解决方法
WITH cte AS ( SELECT tableC.UserID,tableC.email,tableA.url,COUNT(*) OVER (PARTITION BY tableA.url) cnt
FROM tableA
JOIN tableB ON tableA.jove_institution_id = tableB.InstitutionID
JOIN tableC ON tableA.institution_user_id = tableC.UserID )
SELECT UserId,email,url
FROM cte
WHERE cnt > 1;
如果您的版本是 5.x 则使用
SELECT tableC.UserID,tableA.url
FROM ( SELECT url
FROM tableA
GROUP BY url
HAVING COUNT(*) > 1) duplicated
JOIN tableA ON tableA.url = duplicated.url
JOIN tableB ON tableA.jove_institution_id = tableB.InstitutionID
JOIN tableC ON tableA.institution_user_id = tableC.UserID
https://dbfiddle.uk/?rdbms=mysql_8.0&rdbms2=mysql_5.7&fiddle=c2356b72df960978907d0f802fa8817e
,欢迎来到 S/O。您花了一段时间才弄明白旨在解决您的问题的所有部分,有些人只是太矮了,想要一个简单的答案来回复。首先,最好提供您所能提供的实际表/列,因此如果它没有任何“机密”内容,请不要更改它。样本数据总是可以掩盖这一点。
现在,对于您的查询,首先从各个表之间的所有关系开始。为了简单起见,您可以使用别名与更长的表名称。此外,请始终尝试使用 table.column(或别名.column)来防止列来自何处的歧义。
所以我首先从获得所有部分的基本前提开始。我什至认为你不需要 TableB。
select
u.url,u.email
from
TableC u
JOIN TableA i
on u.userID = i.institution_user_id
order by
u.url,u.email
从这个基本查询开始,我所关心的只是让用户(别名 u)加入机构(别名 i)。在这一点上,我不在乎是一个还是多个记录。至少现在我有数据。
现在,您只关心给定 url 包含多个条目的那些。所以现在,我可以通过 URL 应用一个组,并将组连接到电子邮件并应用计数。
select
u.url,group_concat( u.email ) allUserEMails
from
TableC u
JOIN TableA i
on u.userID = i.institution_user_id
-- just add the additional join from one to the next
JOIN TableB ji
on i.jove_institution_id = b.institutionID
group by
u.url
having
count(*) > 1
这是您要找的吗?
如果您还想要所有 ID,也可以添加
group_concat( u.userID) allUserIDs
查看修改后的查询,但如果你没有对 tableB 做任何事情,不知道你为什么需要它。如果只是为了从该表中获取其他名称,那很好