2016-12-30 51 views
-2

我有两个表MYSQL计数与内部联接不工作

1)外展

id profile_id url 
------------------------- 
1 2  www.test.com 
2 3  www.google.com 
3 4  www.example.com 
4 2  www.test2.com 
5 2  www.test3.com 
6 2  www.test4.com 

2)。 outreach_links

id outreach_id start_date    created_at  cost status 
----------------------------------------------------------------------- 
1 1   2016-12-01 00:00:00 2016-12-07 00:00:00 100.00 Approved 
2 1   2016-12-02 00:00:00 2016-12-09 00:00:00 120.00 Approved 
3 1   NUll     2016-12-28 00:00:00 20.00 Pending 
4 1   2016-12-05 00:00:00 2016-12-10 00:00:00 35.00 Approved 
5 1   2016-12-07 00:00:00 2016-12-13 00:00:00 10.00 Approved 
6 2   2016-12-10 00:00:00 2016-12-15 00:00:00 10.00 Pending 
7 2   2016-12-13 00:00:00 2016-12-18 00:00:00 10.00 Approved 
8 2   2016-12-01 00:00:00 2016-12-28 00:00:00 10.00 Pending 
9 2   2016-12-04 00:00:00 2016-12-21 00:00:00 10.00 Approved 
10 2   2016-12-09 00:00:00 2016-12-22 00:00:00 15.00 Pending 

我试图做的月/年计,我认为它的工作,但我认为它不工作,因为“PROFILE_ID”这里的问题是我的查询:

select monthname(date) as Month, year(date) as Year, month(date) as Mn, UNIX_TIMESTAMP(CONCAT(year(date),"-",month(date),"-","01")) as tt, 
(select count(*) from outreach_links where year(outreach_links.created_at) = year and month(outreach_links.created_at) = month and status = "Pending" and created_at>="2016-12-01 00:00:00" and created_at<="2016-12-31 00:00:00") as pp, 
(select count(*) from outreach_links where year(outreach_links.start_date) = year and month(outreach_links.start_date) = month and status = "Approved" and start_date>="2016-12-01 00:00:00" and start_date<="2016-12-31 00:00:00") as aa, 
(select sum(cost) from outreach_links where year(outreach_links.start_date) = year and month(outreach_links.start_date) = month and status = "Approved" and start_date>="2016-12-01 00:00:00" and start_date<="2016-12-31 00:00:00") as cc 
from 
(select year(outreach_links.created_at) as year, month(outreach_links.created_at) as month, outreach_links.created_at as date 
from outreach_links 
inner join outreach on outreach.id = outreach_links.outreach_id 
where outreach_links.created_at>="2016-12-01 00:00:00" and outreach_links.created_at<="2016-12-31 00:00:00" and outreach.profile_id=2 
union 
select year(outreach_links.start_date) as year, month(outreach_links.start_date) as month, outreach_links.start_date as date 
from outreach_links 
inner join outreach on outreach.id = outreach_id 
where start_date>="2016-12-01 00:00:00" and start_date<="2016-12-31 00:00:00" and outreach.profile_id=2) t1 
group by year, month 
order by date 

所以我我所做的日期范围从“2016-12-01 00:00:00”到“2016-12-31 00:00:00”,这些日期范围可以是用户输入的任何日期范围,并尝试根据outreach.profile_id = 2,我的输出是错误的,它计算所有的profile_ids的一切,我不知道为什么

注:这只是一个表的样本,可能有更多的记录和用户inputed日期范围到可能是不同的,我想他们按月/年

这里是我的输出: (其计算所有记录)

array:1 [▼ 
    0 => {#394 ▼ 
    +"Month": "December" 
    +"Year": "2016" 
    +"Mn": "12" 
    +"tt": "1480568400.000000" 
    +"pp": "4" 
    +"aa": "6" 
    +"cc": "285.00" 
    } 
] 

哪项是错误的,应该= 2,这里所需要的输出我想只为PROFILE_ID数:

array:1 [▼ 
    0 => {#394 ▼ 
    +"Month": "December" 
    +"Year": "2016" 
    +"Mn": "12" 
    +"tt": "1480568400.000000" 
    +"pp": "1" 
    +"aa": "4" 
    +"cc": "265.00" 
    } 
] 

正如你可以看到3个计数是错误的,他们假设是: “页”: “1” “AA”: “4” “CC”: “265.00”

这里就是我寻找:

1). **"pp" is Total Pending** Count when status="Pending" based on created_at 
2). **"aa" is Total Approved** Count when status="Approved" based on start_date 
3). **"cc" is Total Cost** Sum of All cost when Status="Approved" and based on start_date 
4). Group by Month & Year of the user imputed Date Range 

这里是一个SQLFIDDLE >>http://sqlfiddle.com/#!9/87dfa8/1

你能帮我解决吗?

感谢

+0

你能用简单的话来描述你想要计算,聚合等吗?仅仅看着查询就很难理解。 –

+0

3件事要计算:1.如果在start_date之间,则批准的总数2.基于created_date范围的总计挂起3。总成本只有在状态获得批准并且在输入范围和所有这些之间的开始日期才需要仅针对输入的profile_id时,请注意日期范围可以由给定用户更改 – user3150060

+0

我想按月和年分组它们,与输出阵列。现在更清楚了吗? – user3150060

回答

-1

我想你想是这样的:

SELECT MONTHNAME(d.date) AS Month 
     , YEAR(d.date)  AS Year 
     , MONTH(d.date)  AS Mn 
     , SUM(IF(l.status = 'Pending' AND l.created_at >= d.date AND l.created_at < d.date + INTERVAL 1 MONTH ,1  ,0)) AS pp 
     , SUM(IF(l.status = 'Approved' AND l.start_date >= d.date AND l.start_date < d.date + INTERVAL 1 MONTH ,1  ,0)) AS aa 
     , SUM(IF(l.status = 'Approved' AND l.start_date >= d.date AND l.start_date < d.date + INTERVAL 1 MONTH ,l.cost,0)) AS cc 
    FROM (SELECT '2016-12-01' + INTERVAL 0 MONTH AS date) d 
    JOIN outreach o 
    ON o.profile_id = 2 
    LEFT 
    JOIN outreach_links l 
    ON l.outreach_id = o.id 
    AND ( ( l.start_date >= d.date + INTERVAL 0 MONTH 
      AND l.start_date < d.date + INTERVAL 1 MONTH 
      ) 
     OR ( l.created_at >= d.date + INTERVAL 0 MONTH 
      AND l.created_at < d.date + INTERVAL 1 MONTH 
      ) 
     ) 
    GROUP BY d.date 

编辑

要使用的起始日期,内嵌沿着指定范围的结束日期查看d可以返回两个日期值。并且外部查询可以引用第二个日期值,在此示例中为d.end_date,以及范围d.date的开始。

SELECT MONTHNAME(d.date) AS Month 
     , YEAR(d.date)  AS Year 
     , MONTH(d.date)  AS Mn 
     , SUM(IF(l.status = 'Pending' AND l.created_at >= d.date AND l.created_at < d.end_date,1  ,0)) AS pp 
     , SUM(IF(l.status = 'Approved' AND l.start_date >= d.date AND l.start_date < d.end_date,1  ,0)) AS aa 
     , SUM(IF(l.status = 'Approved' AND l.start_date >= d.date AND l.start_date < d.end_date,l.cost,0)) AS cc 
    FROM (SELECT '2016-12-01' + INTERVAL 0 MONTH AS date 
       , '2016-12-16' + INTERVAL 0 MONTH AS end_date 
     ) d 
    JOIN outreach o 
    ON o.profile_id = 2 
    LEFT 
    JOIN outreach_links l 
    ON l.outreach_id = o.id 
    AND ( ( l.start_date >= d.date 
      AND l.start_date < d.end_date 
      ) 
     OR ( l.created_at >= d.date 
      AND l.created_at < d.end_date 
      ) 
     ) 
    GROUP BY d.date, d.end_date 
+0

区间是做什么的? – user3150060

+0

我需要保持这两个日期inputed bc这些可能会改变和不需要一个月我可以输入2016-12-01至2016-12-15或任何其他日期,它会计数 – user3150060

+0

我包括第二个版本,它允许结束日期提供。外部查询引用内联视图'd'返回的值,因此这两个日期值仅在查询中提供一次,而不是多次。 http://sqlfiddle.com/#!9/c1f7053/11 – spencer7593