SQL - Display Months as columns - sql-server

I have a SQL Server table that has Start (1-1-2017) and End (1-1-2022) dates for contracts with invoices being generated each month for current and past months.
I would like to display months as columns even when no invoice has been generated, is that possible with just SQL / Pivot tables or a table with dates as calendar must be created?
I have worked with this code so far.
WITH CTE_MyTable AS
(
SELECT
FORMAT(MIN(StartDate), 'yyyy-MM') AS [MyDate]
FROM
MyTable
UNION ALL
SELECT
FORMAT(MIN(DATEADD(month, 1, StartDate)), 'yyyy-MM') AS [MyDate]
FROM
MyTable
WHERE
FORMAT(DATEADD(month, 1, StartDate),'yyyy-MM') <= (SELECT FORMAT(MAX(EndDate), 'yyyy-MM') AS [MyDate] FROM MyTable)
)
SELECT [MyDate]
FROM CTE_ MyTable
GROUP BY MyDate
OPTION (MAXRECURSION 0);

So let's say your table looked like this (using temp variable so you can just copy/paste/test):
DECLARE #sale TABLE(saledate DATE, saleamt MONEY);
INSERT #sale VALUES ('20170103',500),('20170128',266),('20170303',4002),('20170409',25);
Note that I'm only doing 6 months for simplicity. The following query get the count of sales per month (first query) and the sum of the sales for the second query:
DECLARE #sale TABLE(saledate DATE, saleamt MONEY);
INSERT #sale VALUES ('20170103',500),('20170128',266),('20170303',4002),('20170409',25);
SELECT
[201701] = COUNT(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 1 THEN 1 END),
[201702] = COUNT(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 2 THEN 1 END),
[201703] = COUNT(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 3 THEN 1 END),
[201704] = COUNT(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 4 THEN 1 END),
[201705] = COUNT(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 5 THEN 1 END),
[201706] = COUNT(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 6 THEN 1 END)
FROM #sale t;
SELECT
[201701] = ISNULL(SUM(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 1 THEN t.saleamt END),0),
[201702] = ISNULL(SUM(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 2 THEN t.saleamt END),0),
[201703] = ISNULL(SUM(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 3 THEN t.saleamt END),0),
[201704] = ISNULL(SUM(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 4 THEN t.saleamt END),0),
[201705] = ISNULL(SUM(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 5 THEN t.saleamt END),0),
[201706] = ISNULL(SUM(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 6 THEN t.saleamt END),0)
FROM #sale t;
These queries return:
201701 201702 201703 201704 201705 201706
----------- ----------- ----------- ----------- ----------- -----------
2 0 1 1 0 0
201701 201702 201703 201704 201705 201706
--------------------- --------------------- --------------------- --------------------- --------------------- ---------------------
766.00 0.00 4002.00 25.00 0.00 0.00

There is a way to pivot columns in SQL- using the Pivot() function (Microsoft Documentation at: https://learn.microsoft.com/en-us/sql/t-sql/queries/from-using-pivot-and-unpivot?view=sql-server-2017)
To display months as columns (1 to 12) the Pivot() function assigns values to (hard-coded) columns. Implemented correctly, there are NULLS where the aggregation doesn't occur due to lack of records. The implied way to replace NULLS with zeroes is by using the COALESCE() function.
The year values of the pivoted data should be grouped and while there is no specific Group By for a pivot, this is implied by how the SourceTable query is written.
In this example code I use the same exact format as the official documentation; with the exception that I additionally group by year and COALESCE NULLs with 0's.
What I am doing is counting the number of records for a given month and year:
SELECT yearval
,COALESCE([1], 0) [Jan]
,COALESCE([2], 0) [Feb]
,COALESCE([3], 0) [Mar]
,COALESCE([4], 0) [Apr]
,COALESCE([5], 0) [May]
,COALESCE([6], 0) [Jun]
,COALESCE([7], 0) [Jul]
,COALESCE([8], 0) [Aug]
,COALESCE([9], 0) [Sep]
,COALESCE([10], 0) [Oct]
,COALESCE([11], 0) [Nov]
,COALESCE([12], 0) [Dec]
FROM
(SELECT YEAR([Your_Date_Column_Here]) AS [yearval]
,MONTH([Your_Date_Column_Here]) AS [monthval]
FROM [Your_Table_Name_Here]) AS SourceTable
PIVOT
(
COUNT(monthval) FOR monthval IN ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12])
) AS PivotTable
Would produce this output in my test database:
yearval Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
2015 1952 1122 1678 2364 1125 1308 1414 2103 1031 1340 2506 1015
2016 1123 1413 1568 1421 1278 1252 1048 1290 1251 1571 2647 1253
2017 0 0 0 3 0 1241 2377 2714 6724 1388 1521 1243
2018 2127 2118 2449 2330 2687 3833 3279 883 0 0 0 0

Related

Convert Rows into Columns in Sql query to column Time

I have a problem to ask:
Time Pass Fail
-------------------------
08:30 10 2
09:30 12 1
10:30 20 0
11:30 30 40
I am trying to convert rows into column and display such information in below
08:30 09:30 10:30 11:30
------------------------------
10 12 20 30
2 1 0 40
Please help me!
Thank you!
This should do the trick...
IF OBJECT_ID('tempdb..#TestData', 'U') IS NOT NULL
DROP TABLE #TestData;
CREATE TABLE #TestData (
[Time] DATETIME NOT NULL,
Pass INT NOT NULL,
Fail INT NOT null
);
INSERT #TestData (Time, Pass, Fail) VALUES
('08:30',10, 2),
('09:30',12, 1),
('10:30',20, 0),
('11:30',30, 40);
SELECT
[P/F] = CASE WHEN pf.id = 1 THEN 'Pass' ELSE 'Fail' END,
[08:30] = MAX(CASE WHEN td.[Time] = '08:30' THEN pf.Value END),
[09:30] = MAX(CASE WHEN td.[Time] = '09:30' THEN pf.Value END),
[10:30] = MAX(CASE WHEN td.[Time] = '10:30' THEN pf.Value END),
[11:30] = MAX(CASE WHEN td.[Time] = '11:30' THEN pf.Value END)
FROM
#TestData td
CROSS APPLY ( VALUES (1, td.Pass), (2, td.Fail) ) pf (id, Value)
GROUP BY
pf.id;
Results...
P/F 08:30 09:30 10:30 11:30
---- ----------- ----------- ----------- -----------
Pass 10 12 20 30
Fail 2 1 0 40

SQL, using Group by until specific trend (increment, decrement, same)

I would like to know how can i modify my code for considering all the same values of suppose 10 as UP till the time it is incrementing and then down for decrement and SAME if there is no change till the time there is no variation in the value (increment, decrement, same).
Here is my code :
;with etape1 as
(
select ROW_NUMBER() OVER(ORDER BY mnth) AS id,* from [InsideTSQL2008].[alioune].[Sales]
)
,
etape2 as
(
select
a.id, b.mnth AS START , a.mnth AS FINISH ,
a.qty - b.qty AS TREND
FROM
etape1 a
LEFT JOIN etape1 b
on a.id = b.id+1
)
select * from etape2;
My Result is :
id START FINISH TREND
1 NULL 2007-12-01 NULL
2 2007-12-01 2008-01-01 10
3 2008-01-01 2008-02-01 10
4 2008-02-01 2008-03-01 10
5 2008-03-01 2008-04-01 10
6 2008-04-01 2008-05-01 0
7 2008-05-01 2008-06-01 -10
8 2008-06-01 2008-07-01 -10
9 2008-07-01 2008-08-01 -10
10 2008-08-01 2008-09-01 -10
11 2008-09-01 2008-10-01 10
12 2008-10-01 2008-11-01 -10
13 2008-11-01 2008-12-01 20
14 2008-12-01 2009-01-01 10
15 2009-01-01 2009-02-01 10
16 2009-02-01 2009-03-01 -40
My final result as required should be like :
Start End Trend
200712 200712 unknown
200801 200804 UP
200805 200805 SAME
200806 200809 DOWN
200810 200810 UP
200811 200811 DOWN
200812 200812 UP
200903 200903 DOWN
200904 200905 SAME
200906 200907 UP
Any help would be really helpful; Thanks
Took me a few goes (and a few hours), but I think I have what you want:
DECLARE #Sales AS TABLE (mnth datetime, qty int)
INSERT INTO #Sales
SELECT '2016-01-01', 10 UNION ALL
SELECT '2016-02-01', 20 UNION ALL
SELECT '2016-03-01', 30 UNION ALL
SELECT '2016-04-01', 40 UNION ALL
SELECT '2016-05-01', 40 UNION ALL
SELECT '2016-06-01', 30 UNION ALL
SELECT '2016-07-01', 20 UNION ALL
SELECT '2016-08-01', 30 UNION ALL
SELECT '2016-09-01', 40 UNION ALL
SELECT '2016-10-01', 45 UNION ALL
SELECT '2016-11-01', 50
;WITH etape1 AS (
SELECT ROW_NUMBER() OVER(ORDER BY mnth) AS id, * FROM #Sales
)
, etape2 AS (
SELECT id, lag(mnth) OVER (ORDER BY id) AS START, mnth AS FINISH, CASE WHEN qty - LAG(qty) OVER (ORDER BY id) < 0 THEN -1 WHEN qty - LAG(qty) OVER (ORDER BY id) > 0 THEN 1 ELSE 0 END AS TREND
FROM etape1
)
, etape3 AS (
SELECT id, START, FINISH, TREND, lag(TREND) OVER (ORDER BY id) AS PrevTrend
FROM etape2
)
, etape4 AS (
SELECT id, START, FINISH, TREND, SUM(CASE WHEN TREND = PREVTREND THEN 0 ELSE 1 END) OVER (ORDER BY id ROWS UNBOUNDED PRECEDING) AS Change
FROM etape3
)
SELECT MIN(START) AS START, MAX(FINISH) AS FINISH, CASE WHEN MIN(TREND) IS NULL THEN 'Unknown' WHEN MIN(TREND) < 0 THEN 'Down' WHEN MIN(TREND) > 0 THEN 'Up' WHEN MIN(Start) is NULL THEN 'Unknown' ELSE 'Same' END AS TREND
FROM etape4
GROUP BY Change
ORDER BY START
Results are:
START FINISH TREND
NULL 2016-01-01 Unknown
2016-01-01 2016-04-01 Up
2016-04-01 2016-05-01 Same
2016-05-01 2016-07-01 Down
2016-07-01 2016-11-01 Up

SQL count where between dates by month

Consider the below data:
ID Reference Manager LeaseFirstStart LeaseStop
1 KLEIN John 2008-04-02 00:00:00.000 2010-04-01 00:00:00.000
2 HAWKER John 2008-12-18 00:00:00.000 2010-09-17 00:00:00.000
3 SLEEP Bob 2008-01-23 00:00:00.000 2009-01-22 00:00:00.000
4 CODD Bob 2009-08-03 00:00:00.000 2010-08-02 00:00:00.000
5 ALLEN Bob 2008-01-30 00:00:00.000 2009-07-31 00:00:00.000
The earliest month is Jan 2008 and the latest month is Sep 2010.
How can I count the number of leases that were current per month? The output should look like this:
Month Number of Leases
2008-01 2
2008-02 2
2008-03 2
2008-04 3
2008-05 3
2008-06 3
2008-07 3
2008-08 4
… …
Ultimately, I want to use the answer to the question to create the dataset below for use in excel by the user so they can see who had how many leases during the data period.
Month Manager Number of Leases
2008-01 Bob 2
2008-01 John 0
2008-02 Bob 2
2008-02 John 0
2008-03 Bob 2
2008-03 John 0
2008-04 Bob 2
2008-04 John 1
2008-05 Bob 2
2008-05 John 1
2008-06 Bob 2
2008-06 John 1
2008-07 Bob 2
2008-07 John 1
2008-08 Bob 3
2008-08 John 1
… … …
I know I've done it before, but it was a long time ago and I remember it being messy. Thanks in advance!
select sum (no) as no,datet from ( SELECT COUNT (*) as no ,(convert(varchar,datepart (yyyy,[ Start] )) + '-' + convert(varchar, MONTH([ Start] ))) as datet
FROM <tbl>
GROUP BY (convert(varchar,datepart (yyyy,[ Start] )) + '-' + convert(varchar, MONTH([ Start] )))
union SELECT COUNT (*) as no ,(convert(varchar,datepart (yyyy,[ End] )) + '-' + convert(varchar, MONTH([ End] ))) as datet
FROM <tbl>
GROUP BY (convert(varchar,datepart (yyyy,[ End] )) + '-' + convert(varchar, MONTH([ End] )) ) ) t
This is very logical question, finally I created the sql which gives the desired result.. I verified every date and month count and its all ok.
Declare #t table (ID int, Reference varchar(50), Manager varchar(50),LeaseFirstStart datetime,LeaseStop datetime)
insert into #t
values
(1,'KLEIN','John','2008-04-02 00:00:00.000','2010-04-01 00:00:00.000'),
(2,'HAWKER','John','2008-12-18 00:00:00.000','2010-09-17 00:00:00.000'),
(3,'SLEEP','Bob','2008-01-23 00:00:00.000','2009-01-22 00:00:00.000'),
(4,'CODD','Bob','2009-08-03 00:00:00.000','2010-08-02 00:00:00.000'),
(5,'ALLEN','Bob','2008-02-28 00:00:00.000','2009-07-31 00:00:00.000')
declare #lowerdate datetime , #currentdt datetime
select #lowerdate = min(leasefirststart), #currentdt= max(leasestop) from #t
;with cte as
(
select firstday,DATEADD(d, -1, DATEADD(m, DATEDIFF(m, 0, FirstDay) + 1, 0)) Lastday, mng from
( select dateadd(m,datediff(m,0,#lowerdate)+v.number,0) as FirstDay
From master..spt_values v
Where v.type='P' and v.number between 0 and datediff(m, #lowerdate, #currentdt)
) as a
, (select distinct manager mng from #t ) as b
)
select (convert(varchar,datepart (yyyy,FirstDay )) + '-' + convert(varchar, MONTH(FirstDay ))) MonthAndYear ,mng as mng , count( manager ) cnt
from cte
left join #t on
(
firstday between LeaseFirstStart and LeaseStop
or
Lastday between LeaseFirstStart and LeaseStop
) and cte.mng = Manager
group by firstday, mng
order by FirstDay

Count field Pivot table In SQL Server

I have this table - Name : Mytable:
Amount Desc Month Sym code ID
$32,323.00 Bla1 1 121 3 2424221
$4,242.00 Bla1 1 121 3 2424221
$3,535.00 Bla1 1 121 1 3230824
$4,984.00 Bla2 1 433 1 3230824
$47,984.00 Bla2 2 433 1 3230824
$41.00 Bla2 2 433 1 3230824
$3,472.00 Bla6 1 D2 27 2297429
$3,472.00 Bla6 1 D2 27 2297429
$3,239.00 Bla6 2 D2 27 2297429
$4,249.00 Bla8 2 114 24 3434334
ID and Month Stands for for a paycheck. There are 6 paychecks : 1 + 3230824, 2+3230824 etc.
And I want to generate a pivot like this:
Jan Feb
count amount count amount
121 2 40100$ 0 0
433 1 52968$ 1 48025$
D2 1 6944$ 1 3239$
114 0 0 1 4249$
Explanation: 121 is two in Jan because ID = 2424221 got it twice and 3230824 got it one time. The number of of "occurrences" in the paychecks is two.
But, In the amount I sum every thing To get the total sum of money in the paycheck for that Sym.
Same, 433 got the value of 1 in Feb for example because only 3230824 got it (twice).
I started writing this:
SELECT *
FROM (
SELECT
[Sym] as Sym, [Month] as [month], [Amount] as Amount
FROM Mytable
) as T
PIVOT
(
Sum(Amount)
FOR [Month] IN ([1],[2])
)AS piv
Well, The amounts are correct But I don't know how can I pull this count as I explained near the amount in the pivot table.
SELECT
[Sym],
COALESCE(SUM(CASE WHEN [1] IS NULL THEN NULL ELSE [Cnt] END), 0) [Jan Count],
COALESCE(SUM(CASE WHEN [1] IS NULL THEN NULL ELSE [1] END), 0) [Jan Amount],
COALESCE(SUM(CASE WHEN [2] IS NULL THEN NULL ELSE [Cnt] END), 0) [Feb Count],
COALESCE(SUM(CASE WHEN [2] IS NULL THEN NULL ELSE [2] END), 0) [Feb Amount]
FROM (
SELECT
mt1.[Sym] as Sym, mt1.[Month] as [month], mt1.[Amount] as Amount, mt2.[Cnt]
FROM Mytable mt1
JOIN (SELECT COUNT(DISTINCT [ID]) [Cnt], [Sym], [Month]
FROM MyTable
GROUP BY [Sym], [Month]) mt2
ON mt1.[Sym] = mt2.[Sym] AND mt1.[Month] = mt2.[Month]
) as T
PIVOT
(
Sum(Amount)
FOR [Month] IN ([1],[2])
)AS piv
GROUP BY [Sym]
SQL Fiddle

How can I make "month" columns in Sql?

I've got a set of data that looks something like this (VERY simplified):
productId Qty dateOrdered
--------- --- -----------
1 2 10/10/2008
1 1 11/10/2008
1 2 10/10/2009
2 3 10/12/2009
1 1 10/15/2009
2 2 11/15/2009
Out of this, we're trying to create a query to get something like:
productId Year Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
--------- ---- --- --- --- --- --- --- --- --- --- --- --- ---
1 2008 0 0 0 0 0 0 0 0 0 2 1 0
1 2009 0 0 0 0 0 0 0 0 0 3 0 0
2 2009 0 0 0 0 0 0 0 0 0 3 2 0
The way I'm doing this now, I'm doing 12 selects, one for each month, and putting those in temp tables. I then do a giant join. Everything works, but this guy is dog slow.
select productId, Year(dateOrdered) Year
,isnull(sum(case when month(dateOrdered) = 1 then Qty end), 0) Jan
,isnull(sum(case when month(dateOrdered) = 2 then Qty end), 0) Feb
,isnull(sum(case when month(dateOrdered) = 3 then Qty end), 0) Mar
,isnull(sum(case when month(dateOrdered) = 4 then Qty end), 0) Apr
,isnull(sum(case when month(dateOrdered) = 5 then Qty end), 0) May
,isnull(sum(case when month(dateOrdered) = 6 then Qty end), 0) Jun
,isnull(sum(case when month(dateOrdered) = 7 then Qty end), 0) Jul
,isnull(sum(case when month(dateOrdered) = 8 then Qty end), 0) Aug
,isnull(sum(case when month(dateOrdered) = 9 then Qty end), 0) Sep
,isnull(sum(case when month(dateOrdered) = 10 then Qty end), 0) Oct
,isnull(sum(case when month(dateOrdered) = 11 then Qty end), 0) Nov
,isnull(sum(case when month(dateOrdered) = 12 then Qty end), 0) Dec
from Table1
group by productId, Year(dateOrdered)
SQL Fiddle
SELECT productId, YEAR,
ISNULL((SELECT SUM(Qty) FROM Product WHERE productId=X.productId AND YEAR=YEAR(dateOrdered) AND MONTH(dateOrdered)=1),0) as 'JAN',
ISNULL((SELECT SUM(Qty) FROM Product WHERE productId=X.productId AND YEAR=YEAR(dateOrdered) AND MONTH(dateOrdered)=2),0) as 'FEB',
ISNULL((SELECT SUM(Qty) FROM Product WHERE productId=X.productId AND YEAR=YEAR(dateOrdered) AND MONTH(dateOrdered)=3),0) as 'MAR',
ISNULL((SELECT SUM(Qty) FROM Product WHERE productId=X.productId AND YEAR=YEAR(dateOrdered) AND MONTH(dateOrdered)=4),0) as 'APR',
ISNULL((SELECT SUM(Qty) FROM Product WHERE productId=X.productId AND YEAR=YEAR(dateOrdered) AND MONTH(dateOrdered)=5),0) as 'MAY',
ISNULL((SELECT SUM(Qty) FROM Product WHERE productId=X.productId AND YEAR=YEAR(dateOrdered) AND MONTH(dateOrdered)=6),0) as 'JUN',
ISNULL((SELECT SUM(Qty) FROM Product WHERE productId=X.productId AND YEAR=YEAR(dateOrdered) AND MONTH(dateOrdered)=7),0) as 'JUL',
ISNULL((SELECT SUM(Qty) FROM Product WHERE productId=X.productId AND YEAR=YEAR(dateOrdered) AND MONTH(dateOrdered)=8),0) as 'AUG',
ISNULL((SELECT SUM(Qty) FROM Product WHERE productId=X.productId AND YEAR=YEAR(dateOrdered) AND MONTH(dateOrdered)=9),0) as 'SEP',
ISNULL((SELECT SUM(Qty) FROM Product WHERE productId=X.productId AND YEAR=YEAR(dateOrdered) AND MONTH(dateOrdered)=10),0) as 'OCT',
ISNULL((SELECT SUM(Qty) FROM Product WHERE productId=X.productId AND YEAR=YEAR(dateOrdered) AND MONTH(dateOrdered)=11),0) as 'NOV',
ISNULL((SELECT SUM(Qty) FROM Product WHERE productId=X.productId AND YEAR=YEAR(dateOrdered) AND MONTH(dateOrdered)=12),0) as 'DEC'
FROM (
SELECT productId, YEAR(dateOrdered) AS YEAR FROM Product
GROUP BY YEAR(dateOrdered),ProductId) X
For those using Big Query, you can use the following:
select *
from UNNEST(GENERATE_DATE_ARRAY('2015-10-01', '2019-10-01', INTERVAL 1 MONTH))
See https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators?hl=fr#generate_date_array
You can use either a Union of your queries rather than temp tables or use the pivot option.
Here's a forum discussion on it:
Sql Server Forums - Show the row-wise data as column-wise
This qualifies as a presentation concern.
Presentation and SQL don't always mix well.
Isolating your presentation logic in the application layer will:
save you maintenance time—change your application code, but keep your SQL intact;
enable you to more quickly adapt to ephemeral client requirements;
give you more satisfaction than fiddling with a cross-tab or pivot-table that maddeningly does almost exactly what you want.
Below is an example of how you might do this in Python (you can use the excellent pyodbc module to connect to SQL Server):
from collections import defaultdict
from datetime import date
dd = defaultdict(int)
# input
rows = [(1,2,date(2008,10,10)), (1,1,date(2008,11,10)),
(1,2,date(2009,10,10)), (2,3,date(2009,10,12)),
(1,1,date(2009,10,15)), (2,2,date(2009,11,15))]
for row in rows:
# row[0] == productId
# row[1] == Qty
# row[2] == dateOrdered
# pyodbc enables referring to column names by name
dd[(row[2].year, row[2].month, row[0])] += row[1]
presentation_rows = sorted(set((i[0], i[2]) for i in dd.keys()))
for i in presentation_rows:
print i[1], i[0],
for j in range(0,13):
try:
print dd[i[0], j, i[1]],
except IndexError:
print 0,
print
# output
# 1 2008 0 0 0 0 0 0 0 0 0 0 2 1 0
# 1 2009 0 0 0 0 0 0 0 0 0 0 3 0 0
# 2 2009 0 0 0 0 0 0 0 0 0 0 3 2 0
try this. So this code will select data within certain time range, then convert it to a new column. For example, in my sql code: it selects time range between '2014-10-01' and '2014-10-31' from column 'L_dt', then create a new column called "October". In this way, we can lay out data at different columns originated from one column.
select
sum(case when L_dt between '2014-10-01' and '2014-10-31' then 1 else 0 end) October,
sum(case when L_dt between '2014-11-01' and '2014-11-30' then 1 else 0 end) November,
sum(case when L_dt between '2014-12-01' and '2014-12-31' then 1 else 0 end) December
from Table;
If the input looks like:
L_dt
2014-10-13
2014-12-21
2014-11-22
2014-10-10
Then the output will be
+---------+----------+----------+
| October | November | December |
+---------+----------+----------+
| 2 | 1 | 1 |
+---------+----------+----------+

Resources