Mysql where clause breaks calculated query - mysql

wonder if someone can point out the error in my code below. I have mysql query that displays sales leads by month, then calculates % of those converted to sales. If I add where clause to this it breaks the total column as it outputs the same as the Comms column?
Select
q.*,
ROUND(100 * Comms / Total, 2) As Conversion,
If(q.Adviser Is Null, 1, 0) As remove
From
(Select
a.ContactFullName As Adviser,
SUM(YEAR(b.CaseDate) = 2013 AND Month(b.CaseDate) = 1) AS Jan,
SUM(YEAR(b.CaseDate) = 2013 AND Month(b.CaseDate) = 2) As Feb,
SUM(YEAR(b.CaseDate) = 2013 AND Month(b.CaseDate) = 3) As Mar,
SUM(YEAR(b.CaseDate) = 2013 AND Month(b.CaseDate) = 4) As Apr,
SUM(YEAR(b.CaseDate) = 2013 AND Month(b.CaseDate) = 5) As May,
SUM(YEAR(b.CaseDate) = 2013 AND Month(b.CaseDate) = 6) As Jun,
SUM(YEAR(b.CaseDate) = 2013 AND Month(b.CaseDate) = 7) As Jul,
SUM(YEAR(b.CaseDate) = 2013 AND Month(b.CaseDate) = 8) As Aug,
SUM(YEAR(b.CaseDate) = 2013 AND Month(b.CaseDate) = 9) As Sep,
SUM(YEAR(b.CaseDate) = 2013 AND Month(b.CaseDate) = 10) As Oct,
SUM(YEAR(b.CaseDate) = 2013 AND Month(b.CaseDate) = 11) As Nov,
SUM(YEAR(b.CaseDate) = 2013 AND Month(b.CaseDate) = 12) As Dece,
Count(b.CaseID) As Total,
Sum(Case When Year(b.StatusSubmittedDate) = 2013 Then 1 Else 0
End) As Comms
From
tblcontacts a Inner Join
Without WHERE clause it outputs;
Total - Comms - Conversion
479 - 148 - 30.9%
With WHERE clause it outputs;
Total - Comms - Conversion
148 - 148 - 100%
I cant work out why this has happened?
Kind Regards

UPDATE:
I rewrote your whole query:
Select
q.*,
totals.total,
ROUND(100 * Comms / totals.total, 2) As Conversion
If(q.Adviser Is Null, 1, 0) As remove
From
(Select
a.ContactFullName As Adviser,
Sum(Month(b.CaseDate) = 1) As Jan,
Sum(Month(b.CaseDate) = 2) As Feb,
Sum(Month(b.CaseDate) = 3) As Mar,
Sum(Month(b.CaseDate) = 4) As Apr,
Sum(Month(b.CaseDate) = 5) As May,
Sum(Month(b.CaseDate) = 6) As Jun,
Sum(Month(b.CaseDate) = 7) As Jul,
Sum(Month(b.CaseDate) = 8) As Aug,
Sum(Month(b.CaseDate) = 9) As Sep,
Sum(Month(b.CaseDate) = 10) As Oct,
Sum(Month(b.CaseDate) = 11) As Nov,
Sum(Month(b.CaseDate) = 12) As Dece,
Count(b.StatusSubmittedDate) As Comms
From
tblcontacts a Inner Join
tblcases b On a.ContactID = b.ContactAssignedTo
WHERE Year(b.StatusSubmittedDate) = 2013
Group By
a.ContactFullName With Rollup) q
inner join (select a.ContactFullName As Adviser, count(*) as total from
tblcontacts a Inner Join
tblcases b On a.ContactID = b.ContactAssignedTo
WHERE Year(b.StatusSubmittedDate) = 2013
group by Adviser
)totals on q.Adviser = totals.Adviser
Original answer:
To have multiple COUNTS you can workaround like this:
Count(b.CaseID) As Total,
SUM(CASE WHEN YEAR(b.StatusSubmittedDate) = 2013 THEN 1 ELSE 0 END) As Comms,
but this:
ROUND(100 * Count(b.StatusSubmittedDate) / Count(b.CaseID),
won't work, since this calculation has to be done later.
Select
q.*,
ROUND(100 * Comms / Total, 2) As Conversion,
If(q.Adviser Is Null, 1, 0) As remove
From
(Select
a.ContactFullName As Adviser,
Sum(Month(b.CaseDate) = 1 and year(b.CaseDate) = 2012) As Jan,
... Dec,
Count(b.CaseID) As Total,
SUM(CASE WHEN YEAR(b.StatusSubmittedDate) = 2013 THEN 1 ELSE 0 END) As Comms
From
tblcontacts a Inner Join
tblcases b On a.ContactID = b.ContactAssignedTo
Group By
a.ContactFullName With Rollup) q

Related

aggregating values by month, Group by statement in mysql

I have a question on how to group the following statement into months.
Database is MYSQL
Desired result is:
DRNAME, Jan, Feb, Mar, April, May ,June
SISHEN, 0, 0, 100, 250, 450, 500, 0
Result I get is:
DRNAME, Jan, Feb, Mar, April, May ,June
SISHEN, 0, 0, 100, 0, 0, 0,0
SISHEN, 0, 0,0,250,0,0,0
SISHEN, 0, 0, 0,0 , 450, 0, 0
query is
select drname,
case when month(loaddate) = 1 then sum(drvalue) end as 'Jan',<br>
case when month(loaddate) = 2 then sum(drvalue) end as 'Feb',<br>
case when month(loaddate) = 3 then sum(drvalue) end as 'March',<br>
case when month(loaddate) = 4 then sum(drvalue) end as 'April',<br>
case when month(loaddate) = 5 then sum(drvalue) end as 'May',<br>
case when month(loaddate) = 6 then sum(drvalue) end as 'June'<br>
from tblloadschedule<br>
where cancelloadflag = 'N' and drname like 'sish%'<br>
group by drname,month(loaddate)
You need to remove month(loaddate) from the group by clause and then use conditional aggregation instead:
select drname,
sum(case when month(loaddate) = 1 then drvalue else 0 end) as 'Jan',
sum(case when month(loaddate) = 2 then drvalue else 0 end) as 'Feb',
sum(case when month(loaddate) = 3 then drvalue else 0 end) as 'March',
sum(case when month(loaddate) = 4 then drvalue else 0 end) as 'April',
sum(case when month(loaddate) = 5 then drvalue else 0 end) as 'May',
sum(case when month(loaddate) = 6 then drvalue else 0 end) as 'June'
from tblloadschedule
where cancelloadflag = 'N' and drname like 'sish%'
group by drname
Modify your query to take aggregates of the conditional CASE expressions:
SELECT
drname,
SUM(CASE WHEN MONTH(loaddate) = 1 THEN drvalue END) AS Jan,
SUM(CASE WHEN MONTH(loaddate) = 2 THEN drvalue END) AS Feb,
SUM(CASE WHEN MONTH(loaddate) = 3 THEN drvalue END) AS March,
SUM(CASE WHEN MONTH(loaddate) = 4 THEN drvalue END) AS April,
sum(CASE WHEN MONTH(loaddate) = 5 THEN drvalue END) AS May,
sum(CASE WHEN MONTH(loaddate) = 6 THEN drvalue END) AS June
FROM tblloadschedule
WHERE
cancelloadflag = 'N' AND drname LIKE 'sish%'
GROUP BY
drname;
You don't need case which is expensive:
select drname,
sum(if(month(loaddate) = 1 ,drvalue,0) as 'Jan',
sum(if(month(loaddate) = 2 , drvalue ,0) as 'Feb',
sum(if(month(loaddate) = 3 , drvalue ,0) as 'March',
sum(if(month(loaddate) = 4 , drvalue ,0) as 'April',
sum(if(month(loaddate) = 5 , drvalue ,0) as 'May',
sum(if(month(loaddate) = 6 , drvalue ,0) as 'June'
from tblloadschedule
where cancelloadflag = 'N' and drname like 'sish%'
group by drname
EDIT without use of IF:
select drname,
sum((month(loaddate) = 1 ) * drvalue) as 'Jan',
sum((month(loaddate) = 2 ) * drvalue) as 'Feb',
sum((month(loaddate) = 3 ) * drvalue) as 'March',
sum((month(loaddate) = 4 ) * drvalue) as 'April',
sum((month(loaddate) = 5 ) * drvalue) as 'May',
sum((month(loaddate) = 6 ) * drvalue) as 'June'
from tblloadschedule
where cancelloadflag = 'N' and drname like 'sish%'
group by drname
The method from A. Colonna with the IF definitely worked out more efficient on the server and returned the desired results.
Many thanks to all who commented.
The code I used is:
select drname,
sum((month(loaddate) = 1 ) * drvalue) as 'Jan',
sum((month(loaddate) = 2 ) * drvalue) as 'Feb',
sum((month(loaddate) = 3 ) * drvalue) as 'March',
sum((month(loaddate) = 4 ) * drvalue) as 'April',
sum((month(loaddate) = 5 ) * drvalue) as 'May',
sum((month(loaddate) = 6 ) * drvalue) as 'June'
from tblloadschedule
where cancelloadflag = 'N'
group by drname

inner join with pivot condition sql

I currently have the following sql query:
SELECT
name,
SUM( IF( MONTH(date) = 1, amount, 0) ) AS jan,
SUM( IF( MONTH(date) = 2, amount, 0) ) AS feb,
SUM( IF( MONTH(date) = 3, amount, 0) ) AS mar,
SUM( IF( MONTH(date) = 4, amount, 0) ) AS apr,
SUM( IF( MONTH(date) = 5, amount, 0) ) AS mei,
SUM( IF( MONTH(date) = 6, amount, 0) ) AS jun,
SUM( IF( MONTH(date) = 7, amount, 0) ) AS jul,
SUM( IF( MONTH(date) = 8, amount, 0) ) AS agu,
SUM( IF( MONTH(date) = 9, amount, 0) ) AS sep,
SUM( IF( MONTH(date) = 10, amount, 0) ) AS okt,
SUM( IF( MONTH(date) = 11, amount, 0) ) AS nov,
SUM( IF( MONTH(date) = 12, amount, 0) ) AS des,
SUM( amount ) AS total
FROM iuran_detail
WHERE (
date BETWEEN '$date_first' AND '$date_last'
) GROUP BY name;
I want modification with 2 tables sql, user table (along with group) and amount.
I want to combine the inner join or another way, to get the following result (e.g by group A):
thanks
Note: If joining tables it is best practice to prefix EVERY column reference with either the source table name OR by an alias given to the source table (I use the latter). "date" is a terrible column name as it is also used by SQL itself and can cause confusion, so below I have used the MySQL backticks to reference that column, in SQL-Server you could use [date] instead.
SELECT
u.name,
SUM( IF( MONTH(`date`) = 1, d.amount, 0) ) AS jan,
SUM( IF( MONTH(`date`) = 2, d.amount, 0) ) AS feb,
SUM( IF( MONTH(`date`) = 3, d.amount, 0) ) AS mar,
SUM( IF( MONTH(`date`) = 4, d.amount, 0) ) AS apr,
SUM( IF( MONTH(`date`) = 5, d.amount, 0) ) AS mei,
SUM( IF( MONTH(`date`) = 6, d.amount, 0) ) AS jun,
SUM( IF( MONTH(`date`) = 7, d.amount, 0) ) AS jul,
SUM( IF( MONTH(`date`) = 8, d.amount, 0) ) AS agu,
SUM( IF( MONTH(`date`) = 9, d.amount, 0) ) AS sep,
SUM( IF( MONTH(`date`) = 10, d.amount, 0) ) AS okt,
SUM( IF( MONTH(`date`) = 11, d.amount, 0) ) AS nov,
SUM( IF( MONTH(`date`) = 12, d.amount, 0) ) AS des,
SUM( d.amount ) AS total
FROM table_trx d
INNER JOIN table_user u on d.user_id = u.id
WHERE (
d.`date` BETWEEN '$`date`_first' AND '$`date`_last'
) GROUP BY u.name;
Personally I do not like using IF() as an alternative to the more standard CASE expression as it is more broadly supported in SQL databases.
SELECT
u.name,
SUM( case when MONTH(`date`) = 1 then d.amount else 0 end ) AS jan,
SUM( case when MONTH(`date`) = 2 then d.amount else 0 end ) AS feb,
SUM( case when MONTH(`date`) = 3 then d.amount else 0 end ) AS mar,
SUM( case when MONTH(`date`) = 4 then d.amount else 0 end ) AS apr,
SUM( case when MONTH(`date`) = 5 then d.amount else 0 end ) AS mei,
SUM( case when MONTH(`date`) = 6 then d.amount else 0 end ) AS jun,
SUM( case when MONTH(`date`) = 7 then d.amount else 0 end ) AS jul,
SUM( case when MONTH(`date`) = 8 then d.amount else 0 end ) AS agu,
SUM( case when MONTH(`date`) = 9 then d.amount else 0 end ) AS sep,
SUM( case when MONTH(`date`) = 10 then d.amount else 0 end ) AS okt,
SUM( case when MONTH(`date`) = 11 then d.amount else 0 end ) AS nov,
SUM( case when MONTH(`date`) = 12 then d.amount else 0 end ) AS des,
SUM( d.amount ) AS total
FROM table_trx d
INNER JOIN table_user u on d.user_id = u.id
WHERE (
d.`date` BETWEEN '$`date`_first' AND '$`date`_last'
) GROUP BY u.name;

mysql where clause spanning multiple years?

I have mysql query that outputs years leads v sales and calculates the conversions rates which worked great in 2012 as it only held a years data. Now its 2013 I need to change how it works but have become stuck. If a lead came in December 2012, then became a sale in 2013 its is ommitted from my query output as it only asks for CaseDate of 2013.
Select
q.*,
ROUND(100 * q.Comms / q.Total, 2) As Conversion,
If(q.Adviser Is Null, 1, 0) As remove
From
(Select
a.ContactFullName As Adviser,
Sum(Year(b.CaseDate) = 2013 And Month(b.CaseDate) = 1) As Jan,
Sum(Year(b.CaseDate) = 2013 And Month(b.CaseDate) = 2) As Feb,
Sum(Year(b.CaseDate) = 2013 And Month(b.CaseDate) = 3) As Mar,
..... Dec
Sum(Case
When Year(b.CaseDate) = 2013 And Month(b.CaseDate) Between '1'
And '12' Then 1 Else 0 End) As Total,
Sum(Case When (Year(b.CaseDate) = 2012 Or Year(b.CaseDate) = 2013) And Year(b.StatusSubmittedDate) = ".(int)$_POST['year']." And Month(b.StatusSubmittedDate) Between ".(int)$_POST['start']." And ".(int)$_POST['end']." Then 1 Else 0 End) As Comms
From
tblcontacts a Inner Join
tblcases b On a.ContactID = b.ContactAssignedTo
Group By
a.ContactFullName With Rollup) q
This works;
Sum(Case When (Year(b.CaseDate) = 2012 Or Year(b.CaseDate) = 2013) And Year(b.StatusSubmittedDate) = 2013 And Month(b.CaseDate) Between '1' And '12' Then 1 Else 0 End) As Comms
This donly shows leads entered & submitted in 2013;
Sum(Case When (Year(b.CaseDate) = 2012 Or Year(b.CaseDate) = 2013) And Year(b.StatusSubmittedDate) = ".(int)$_POST['year']." And Month(b.CaseDate) Between ".(int)$_POST['start']." And ".(int)$_POST['end']." Then 1 Else 0 End) As Comms
Many Thanks
It depends on your business logic. If the logic says you only show leads that came in the same year, then your code is perfectly correct as-is (as-was?). If you want to include 2012 or 2013 (which it looks like you do), you need to spell it out completely, the server doesn't understand "2012 or 2013"
Sum(Case When (Year(b.CaseDate) = 2012 Or Year(b.CaseDate) = 2013) And Year(....
Notice the parenthesis around the Or statement, this is to make sure that CaseYear=2012 or CaseYear=2013 and SubmitYear=2013 is treated as (CaseYear=2012 or CaseYear=2013) and SubmitYear=2013 instead of CaseYear=2012 or (CaseYear=2013 and SubmitYear=2013)
Of course if the business logic does not care about the CaseYear, then take that out of the Sum.

Mysql filter query from drop down box

Good morning, I have the mysql query below to display the years sales which worked fine until the year changed as it now shows Jan 2012 & Jan 2013 combined.
To try to resolve I placed a drop down form box (id=YearSelect) with value of 2012 & 2013, is it possible I can control this query with the value selected? Should the end user select 2012 then that value would be sent to column Year as a type of where clause?
<form id="yearselect">
<select name="year">
<option value="">Select year </option>
<option value="2012">2012</option>
<option value="2013">2013</option>
</select>
</form>
Select
*,
If(q.Adviser Is Null, 1, 0) As remove
From
(Select
a.ContactFullName As Adviser,
YEAR(b.CaseDate) As Year,
Sum(If(Month(b.StatusSubmittedDate) = 1, b.CaseCommission, 0)) As Jan,
Sum(If(Month(b.StatusSubmittedDate) = 2, b.CaseCommission, 0)) As Feb,
Sum(If(Month(b.StatusSubmittedDate) = 3, b.CaseCommission, 0)) As Mar,
Sum(If(Month(b.StatusSubmittedDate) = 4, b.CaseCommission, 0)) As Apr,
Sum(If(Month(b.StatusSubmittedDate) = 5, b.CaseCommission, 0)) As May,
Sum(If(Month(b.StatusSubmittedDate) = 6, b.CaseCommission, 0)) As Jun,
Sum(If(Month(b.StatusSubmittedDate) = 7, b.CaseCommission, 0)) As Jul,
Sum(If(Month(b.StatusSubmittedDate) = 8, b.CaseCommission, 0)) As Aug,
Sum(If(Month(b.StatusSubmittedDate) = 9, b.CaseCommission, 0)) As Sep,
Sum(If(Month(b.StatusSubmittedDate) = 10, b.CaseCommission, 0)) As Oct,
Sum(If(Month(b.StatusSubmittedDate) = 11, b.CaseCommission, 0)) As Nov,
Sum(If(Month(b.StatusSubmittedDate) = 12, b.CaseCommission, 0)) As Decb,
Sum(b.CaseCommission) As Total
From
tblcontacts a Inner Join
tblcases b On a.ContactID = b.ContactAssignedTo
Where
WHERE Year(b.StatusSubmittedDate) = ".(int)$_POST['year']."
Group By
a.ContactFullName WITH ROLLUP
Having
Sum(b.CaseCommission) > 0.01) q
Order By
If(q.Adviser Is Null, 1, 0), q.Total Desc
Any advice appreciated.
What about changing this WHERE:
Where
b.StatusSubmittedDate > '2012 - 01 - 01'
to:
Where
YEAR(b.StatusSubmittedDate) = ".(int)$YEAR_VALUE_FROM_DROPDOWN."
That should be enough...
Considering the PHP tag I assume you are showing the results on a PHP bases page. You can use the following code to do what you want.
<form id="yearselect" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>" >
<select name='selyear' onchange='document.getElementById("yearselect").submit()'>
<option value=''> - Select year </option>
<option value='2012'>2012</option>
<option value='2013'>2013</option>
</select>
</form>
<?
$y = date("Y");
if (isset($_POST['selyear']))
{
if (checkdate(1, 1, $_POST['selyear']) && $_POST['selyear']>=2012)
$y = $_POST['selyear'];
}
$query = 'Select
*,
If(q.Adviser Is Null, 1, 0) As remove
From
(Select
a.ContactFullName As Adviser,
YEAR(b.CaseDate) As Year,
Sum(If(Month(b.StatusSubmittedDate) = 1, b.CaseCommission, 0)) As Jan,
Sum(If(Month(b.StatusSubmittedDate) = 2, b.CaseCommission, 0)) As Feb,
Sum(If(Month(b.StatusSubmittedDate) = 3, b.CaseCommission, 0)) As Mar,
Sum(If(Month(b.StatusSubmittedDate) = 4, b.CaseCommission, 0)) As Apr,
Sum(If(Month(b.StatusSubmittedDate) = 5, b.CaseCommission, 0)) As May,
Sum(If(Month(b.StatusSubmittedDate) = 6, b.CaseCommission, 0)) As Jun,
Sum(If(Month(b.StatusSubmittedDate) = 7, b.CaseCommission, 0)) As Jul,
Sum(If(Month(b.StatusSubmittedDate) = 8, b.CaseCommission, 0)) As Aug,
Sum(If(Month(b.StatusSubmittedDate) = 9, b.CaseCommission, 0)) As Sep,
Sum(If(Month(b.StatusSubmittedDate) = 10, b.CaseCommission, 0)) As Oct,
Sum(If(Month(b.StatusSubmittedDate) = 11, b.CaseCommission, 0)) As Nov,
Sum(If(Month(b.StatusSubmittedDate) = 12, b.CaseCommission, 0)) As Decb,
Sum(b.CaseCommission) As Total
From
tblcontacts a Inner Join
tblcases b On a.ContactID = b.ContactAssignedTo
Where
b.StatusSubmittedDate > \''.$y.' - 01 - 01\'
AND b.StatusSubmittedDate < \''.$y.' - 12 - 31\'
Group By
a.ContactFullName WITH ROLLUP
Having
Sum(b.CaseCommission) > 0.01) q
Order By
If(q.Adviser Is Null, 1, 0), q.Total Desc'
//output results
?>
Now I didnt check your query as you mentioned it works. Also instead of posting the form on changing the select list, you could also alter it to use AJAX or whatever to make it better. But I guess you get the idea.
Also I now check for a valid year, not just 2012 or 2013. That depends on what you want.

Msql Crosstab month rows as columns?

Good morning, I am unsuccessfully trying to create a report using mysql/php, I would like to have rows as columns similar to Access Crosstab or Excel Pivot. I have sales staff & monthly sales which I would like to display across the page with month as column headers.
My query below outputs the data but every salesperson has a row for every month which doesnt read very well,
Jan | Feb | Mar | April
Sales1
Sales2
Sales3
Sales4
Select
tblcontacts.ContactFullName,
Count(tblcases.CaseID) As cases,
MonthName(tblcases.CaseDate) As Monthly
From
tblcases Inner Join
tblcontacts On tblcases.ContactAssignedTo =
tblcontacts.ContactID
Group By
tblcontacts.ContactFullName,
MonthName(tblcases.CaseDate)
with rollup
Ant advice or pointers appreciated, I have researched but most of it went right over my head!
Kind regards
What you can do is simply group by each contact and use conditional aggregation to count rows based on each month:
SELECT
a.ContactFullName,
SUM(MONTH(b.CaseDate) = 1) AS Jan,
SUM(MONTH(b.CaseDate) = 2) AS Feb,
SUM(MONTH(b.CaseDate) = 3) AS Mar,
SUM(MONTH(b.CaseDate) = 4) AS Apr,
SUM(MONTH(b.CaseDate) = 5) AS May,
SUM(MONTH(b.CaseDate) = 6) AS Jun,
SUM(MONTH(b.CaseDate) = 7) AS Jul,
SUM(MONTH(b.CaseDate) = 8) AS Aug,
SUM(MONTH(b.CaseDate) = 9) AS Sep,
SUM(MONTH(b.CaseDate) = 10) AS Oct,
SUM(MONTH(b.CaseDate) = 11) AS Nov,
SUM(MONTH(b.CaseDate) = 12) AS Dec
FROM
tblcontacts a
INNER JOIN
tblcases b ON a.ContactID = b.ContactAssignedTo
GROUP BY
a.ContactFullName
Edit: As per your comments to this answer: to get a price sum of each month, you can do something like:
SELECT
a.ContactFullName,
SUM(IF(MONTH(b.CaseDate) = 1, b.price, 0)) AS Jan,
SUM(IF(MONTH(b.CaseDate) = 2, b.price, 0)) AS Feb,
SUM(IF(MONTH(b.CaseDate) = 3, b.price, 0)) AS Mar,
SUM(IF(MONTH(b.CaseDate) = 4, b.price, 0)) AS Apr,
SUM(IF(MONTH(b.CaseDate) = 5, b.price, 0)) AS May,
SUM(IF(MONTH(b.CaseDate) = 6, b.price, 0)) AS Jun,
SUM(IF(MONTH(b.CaseDate) = 7, b.price, 0)) AS Jul,
SUM(IF(MONTH(b.CaseDate) = 8, b.price, 0)) AS Aug,
SUM(IF(MONTH(b.CaseDate) = 9, b.price, 0)) AS Sep,
SUM(IF(MONTH(b.CaseDate) = 10, b.price, 0)) AS Oct,
SUM(IF(MONTH(b.CaseDate) = 11, b.price, 0)) AS Nov,
SUM(IF(MONTH(b.CaseDate) = 12, b.price, 0)) AS Dec
FROM
tblcontacts a
INNER JOIN
tblcases b ON a.ContactID = b.ContactAssignedTo
GROUP BY
a.ContactFullName
Basically, for each row, if the casedate is in a particular month, pass the value of the price column to the SUM aggregation, otherwise, just pass it 0.
Select
tblcontacts.ContactFullName,
sum(case when MonthName(tblcases.CaseDate)='January' then 1 else 0 end) as January,
sum(case when MonthName(tblcases.CaseDate)='February' then 1 else 0 end) as February,
.
.
sum(case when MonthName(tblcases.CaseDate)='December' then 1 else 0 end) as December,
From
tblcases Inner Join
tblcontacts On tblcases.ContactAssignedTo =
tblcontacts.ContactID
Group By
tblcontacts.ContactFullName