2016-08-23 87 views
0

我想在同一個查詢中從多個表中進行計數,並且2個計數的結果是完全錯誤的。我在此查詢中使用以下3個表:從子表中選擇2個不同子表的計數

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 

我該如何糾正這種情況,而不使用子選擇中的子選擇(這對性能來說會很糟糕)?

編輯:我相信,我幾乎有這個工作,但必須有寫這個查詢一個更好的方法(也,它似乎是分組的assignments通過lead_id):

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 
+0

可以提供相同的一些記錄? –

回答

0
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 

希望這會有所幫助。嘗試一下。

+0

這不完整。它還解決了我已經工作的列,並完全刪除了我試圖從結果集中修復的兩個有問題的列。 – kjdion84

0

鑑於這一數據

/* 
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 | 
+----+-------------+------+-----------+---------+----------+-------+----------+----------+