【问题标题】:Select counts from 2 different tables without subselect within subselect从 2 个不同的表中选择计数,而子选择中没有子选择
【发布时间】:2016-08-23 03:42:44
【问题描述】:

我正在尝试对同一查询中的多个表进行计数,但其中 2 个计数的结果完全错误。我在此查询中使用了以下 3 个表:

CREATE TABLE `assignments` (
    `id` int(11) NOT NULL,
    `lead_id` int(11) NOT NULL,
    `buyer_id` int(11) NOT NULL,
    `refunded` int(11) NOT NULL DEFAULT '0',
    `date_assigned` int(11) NOT NULL,
    `date_refunded` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

CREATE TABLE `leads` (
    `id` int(11) NOT NULL,
    `vertical_id` int(11) NOT NULL,
    `source_id` int(11) NOT NULL,
    `agent_id` varchar(255) DEFAULT NULL,
    `status_id` int(11) NOT NULL DEFAULT '0',
    `completeness` enum('Partial','Complete') DEFAULT NULL,
    `freshness` enum('New','Duplicate') NOT NULL,
    `date_created` int(11) NOT NULL,
    `date_updated` int(11) NOT NULL,
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

CREATE TABLE `verticals` (
    `id` int(11) NOT NULL,
    `name` varchar(255) NOT NULL,
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

我想要做的是抓取结果并将它们放入这样的表格中:

Name        New Duplicate Partial Complete Total Assigned Refunded
Automotive  4   1         3       2        5     36       9
Education   16  7         9       14       23    36       9

前 5 列编号正确。问题是分配和退还的列号是完全错误的。这是我的查询:

select v.*,
(select count(*) from `leads` where vertical_id=v.id and `freshness`='New' and `date_created` between 1470009600 and 1471923227) as `new`,
(select count(*) from `leads` where vertical_id=v.id and `freshness`='Duplicate' and `date_created` between 1470009600 and 1471923227) as `duplicate`,
(select count(*) from `leads` where vertical_id=v.id and `completeness`='Partial' and `date_created` between 1470009600 and 1471923227) as `partial`,
(select count(*) from `leads` where vertical_id=v.id and `completeness`='Complete' and `date_created` between 1470009600 and 1471923227) as `complete`,
(select count(*) from `leads` where vertical_id=v.id and `date_created` between 1470009600 and 1471923227) as `total`,
(select count(*) from `assignments` where lead_id=l.id and `refunded`=0) as `assigned`,
(select count(*) from `assignments` where lead_id=l.id and `refunded`=1) as `refunded`
from `verticals` as v
left join `leads` as l on (l.vertical_id = v.id)
where l.date_created between 1470009600 and 1471923227
group by v.id

如何在不使用子选择中的子选择的情况下更正此问题(这对性能来说很糟糕)?

编辑:我相信我几乎可以完成这项工作,但必须有更好的方法来编写此查询(另外,它似乎是通过 lead_idassignments 进行分组):

select o.*,
(select count(*) from `leads` where {$sql_column}=o.id and `freshness`='New' and `date_created` between {$date_from} and {$date_to}) as `new`,
(select count(*) from `leads` where {$sql_column}=o.id and `freshness`='Duplicate' and `date_created` between {$date_from} and {$date_to}) as `duplicate`,
(select count(*) from `leads` where {$sql_column}=o.id and `completeness`='Partial' and `date_created` between {$date_from} and {$date_to}) as `partial`,
(select count(*) from `leads` where {$sql_column}=o.id and `completeness`='Complete' and `date_created` between {$date_from} and {$date_to}) as `complete`,
(select count(*) from `leads` where {$sql_column}=o.id and `date_created` between {$date_from} and {$date_to}) as `total`,
(select count(*) from `assignments` where `lead_id` in 
    (select `id` from `leads` where {$sql_column}=o.id and `date_created` between {$date_from} and {$date_to}) and `refunded`=0) as `assigned`,
(select count(*) from `assignments` where `lead_id` in 
    (select `id` from `leads` where {$sql_column}=o.id and `date_created` between {$date_from} and {$date_to}) and `refunded`=1) as `refunded`
from {$sql_object} as o

【问题讨论】:

  • 你能提供一些相同的记录吗?

标签: mysql select count subquery


【解决方案1】:
select v.*,COUNT(CASE WHEN `freshness`='New' THEN freshness END) as new,COUNT(CASE WHEN `freshness`='Duplicate' THEN freshness END) as duplicate from `verticals` as v left join `leads` as l on (l.vertical_id = v.id) where l.date_created between 1470009600 and 1471923227 group by v.id

希望这会有所帮助。试试看。

【讨论】:

  • 这不完整。它还解决了我已经使用的列,并从结果集中完全删除了我试图重点修复的 2 个有问题的列。
【解决方案2】:

鉴于此数据

/*
truncate table verticals;
INSERT INTO VERTICALS VALUES
(1,'Automotive'),(2,'Educational');

truncate table leads;
insert into leads values
(1,1,1,1,1,'Partial','New', 1470009600, 1470009600),
(2,2,1,1,1,'Partial','New', 1470009600, 1470009600),
(3,1,1,1,1,'Partial','Duplicate', 1470009600, 1470009600),
(4,2,1,1,1,'Partial','Duplicate', 1470009600, 1470009600),
(5,1,1,1,1,'Complete','New', 1470009600, 1470009600),
(6,2,1,1,1,'Complete','New', 1470009600, 1470009600),
(7,1,1,1,1,'Complete','Duplicate', 1470009600, 1470009600),
(8,2,1,1,1,'Complete','Duplicate', 1470009600, 1470009600),
(9,1,1,1,1,'Complete','New', 1470009600, 1470009600),
(10,1,1,1,1,'Complete','Duplicate', 1470009600, 1470009600);

truncate table assignments;
insert into assignments values
(1,1,1,0,1470009600, 1470009600),
(2,2,1,1,1470009600, 1470009600),
(3,3,1,0,1470009600, 1470009600),
(4,4,1,1,1470009600, 1470009600),
(5,5,1,1,1470009600, 1470009600);
*/

这个查询

select v.*,
SUM(CASE WHEN L.`freshness`='New' THEN 1 ELSE 0 END) as `new`,
SUM(CASE WHEN L.`freshness`='Duplicate' THEN 1 ELSE 0 END) AS `duplicate`,
SUM(CASE WHEN L.`completeness`='Partial' THEN 1 ELSE 0 END)  as `partial`,
SUM(CASE WHEN L.`completeness`='Complete' THEN 1 ELSE 0 END)  as `complete`,
count(L.id)  as `total`,
SUM(CASE WHEN A.`refunded`=0 THEN 1 ELSE 0 END) as `assigned`,
SUM(CASE WHEN A.`refunded`=1 THEN 1 ELSE 0 END) as `refunded`
from `verticals` as v
left join `leads` as l on (l.vertical_id = v.id) AND  (l.date_created between 1470009600 and 1471923227)
LEFT JOIN ASSIGNMENTS A ON A.LEAD_ID = L.ID
group by v.id

结果

+----+-------------+------+-----------+---------+----------+-------+----------+----------+
| id | name        | new  | duplicate | partial | complete | total | assigned | refunded |
+----+-------------+------+-----------+---------+----------+-------+----------+----------+
|  1 | Automotive  |    3 |         3 |       2 |        4 |     6 |        2 |        1 |
|  2 | Educational |    2 |         2 |       2 |        2 |     4 |        0 |        2 |
+----+-------------+------+-----------+---------+----------+-------+----------+----------+

【讨论】:

    猜你喜欢
    • 2014-02-23
    • 1970-01-01
    • 1970-01-01
    • 2015-11-24
    • 1970-01-01
    • 1970-01-01
    • 2019-10-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多