从不同的表中获取总和和计数
Getting a Sum and Count from Different Tables
我猜这太局限了,但我想不出一种方法让它更通用(这可能是我无法在 Google 上找到答案的原因)。
我们有一个应用程序可以跟踪我们业务的联系人。这些联系人(联系人 table)可以通过 phone (Contact_Phone table) 或通过电子邮件 (Contact_Email) 联系。如果通过 phone 联系用户,代理会跟踪总秒数 (Contact_Phone.totalSeconds)。通过一段业务逻辑,我无法控制电子邮件联系人被视为一秒钟。可能仅通过电子邮件、phone 或两者联系用户。
我正在尝试生成一份报告,说明我们花了多长时间联系每个用户,但我无法获得预期的结果。
表:
CREATE TABLE IF NOT EXISTS `Contact` (
`id` INT NOT NULL AUTO_INCREMENT ,
`name` VARCHAR(45) NULL ,
PRIMARY KEY (`id`) )
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS `Contact_Email` (
`id` INT NOT NULL AUTO_INCREMENT ,
`ContactId` INT NULL ,
PRIMARY KEY (`id`) ,
INDEX `contact_email_contact_idx` (`ContactId` ASC) ,
CONSTRAINT `contact_email_contact`
FOREIGN KEY (`ContactId` )
REFERENCES `Contact` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS `Contact_Phone` (
`id` INT NOT NULL AUTO_INCREMENT ,
`totalSeconds` INT NULL ,
`ContactId` INT NULL ,
PRIMARY KEY (`id`) ,
INDEX `Contact_Phone_contact_idx` (`ContactId` ASC) ,
CONSTRAINT `Contact_Phone_contact`
FOREIGN KEY (`ContactId` )
REFERENCES `Contact` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
测试数据:
insert into Contact (id, name) values (1, 'Scott');
insert into Contact (id, name) values (2, 'Joe');
insert into Contact_Phone (totalSeconds, ContactId) values (10, 2);
insert into Contact_Phone (totalSeconds, ContactId) values (100, 2);
insert into Contact_Email (ContactId) values (1);
insert into Contact_Email (ContactId) values (1);
insert into Contact_Email (ContactId) values (2);
查询:
select
name,
(select sum(totalSeconds) from Contact_Phone where Contact_Phone.ContactId = Contact.id)
+
(select count(*) from Contact_Email where Contact_Email.ContactId = Contact.id)
from Contact;
预期结果:
Joe 111
Scott 2
实际结果:
Joe 111
Scott null
谢谢
像这样使用汇总和 LEFT JOIN 操作怎么样?
SELECT Contact.name,
COALESCE(p.seconds,0) + COALESCE(e.seconds,0) seconds
FROM Contact.Name
LEFT JOIN (
SELECT ContactID AS id,
SUM(totalSeconds) AS seconds
FROM ContactPhone
GROUP BY ContactID
) p ON Contact.id = p.id
LEFT JOIN (
SELECT ContactID AS id,
COUNT(*) AS seconds
FROM ContactEmail
GROUP BY ContactID
) e ON Contact.id = e.id
LEFT JOIN
操作将保留您的结果行,其中一个或另一个 "seconds" 计算为 NULL。并且,COALESCE 操作将阻止您的查询尝试对 NULL 值进行算术运算,这会产生 NULL。
我猜这太局限了,但我想不出一种方法让它更通用(这可能是我无法在 Google 上找到答案的原因)。
我们有一个应用程序可以跟踪我们业务的联系人。这些联系人(联系人 table)可以通过 phone (Contact_Phone table) 或通过电子邮件 (Contact_Email) 联系。如果通过 phone 联系用户,代理会跟踪总秒数 (Contact_Phone.totalSeconds)。通过一段业务逻辑,我无法控制电子邮件联系人被视为一秒钟。可能仅通过电子邮件、phone 或两者联系用户。
我正在尝试生成一份报告,说明我们花了多长时间联系每个用户,但我无法获得预期的结果。
表:
CREATE TABLE IF NOT EXISTS `Contact` (
`id` INT NOT NULL AUTO_INCREMENT ,
`name` VARCHAR(45) NULL ,
PRIMARY KEY (`id`) )
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS `Contact_Email` (
`id` INT NOT NULL AUTO_INCREMENT ,
`ContactId` INT NULL ,
PRIMARY KEY (`id`) ,
INDEX `contact_email_contact_idx` (`ContactId` ASC) ,
CONSTRAINT `contact_email_contact`
FOREIGN KEY (`ContactId` )
REFERENCES `Contact` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS `Contact_Phone` (
`id` INT NOT NULL AUTO_INCREMENT ,
`totalSeconds` INT NULL ,
`ContactId` INT NULL ,
PRIMARY KEY (`id`) ,
INDEX `Contact_Phone_contact_idx` (`ContactId` ASC) ,
CONSTRAINT `Contact_Phone_contact`
FOREIGN KEY (`ContactId` )
REFERENCES `Contact` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
测试数据:
insert into Contact (id, name) values (1, 'Scott');
insert into Contact (id, name) values (2, 'Joe');
insert into Contact_Phone (totalSeconds, ContactId) values (10, 2);
insert into Contact_Phone (totalSeconds, ContactId) values (100, 2);
insert into Contact_Email (ContactId) values (1);
insert into Contact_Email (ContactId) values (1);
insert into Contact_Email (ContactId) values (2);
查询:
select
name,
(select sum(totalSeconds) from Contact_Phone where Contact_Phone.ContactId = Contact.id)
+
(select count(*) from Contact_Email where Contact_Email.ContactId = Contact.id)
from Contact;
预期结果:
Joe 111
Scott 2
实际结果:
Joe 111
Scott null
谢谢
像这样使用汇总和 LEFT JOIN 操作怎么样?
SELECT Contact.name,
COALESCE(p.seconds,0) + COALESCE(e.seconds,0) seconds
FROM Contact.Name
LEFT JOIN (
SELECT ContactID AS id,
SUM(totalSeconds) AS seconds
FROM ContactPhone
GROUP BY ContactID
) p ON Contact.id = p.id
LEFT JOIN (
SELECT ContactID AS id,
COUNT(*) AS seconds
FROM ContactEmail
GROUP BY ContactID
) e ON Contact.id = e.id
LEFT JOIN
操作将保留您的结果行,其中一个或另一个 "seconds" 计算为 NULL。并且,COALESCE 操作将阻止您的查询尝试对 NULL 值进行算术运算,这会产生 NULL。