Keep only Day from Date in column name - sql

i have created a stored procedure by online help to generate a monthly attendance report
USE [Attendace]
GO
/****** Object: StoredProcedure [dbo].[PerDayAttendance] Script Date: 04/11/2018 20:16:05 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[PerDayAttendance]
#STARTDATE DATE,
#ENDDATE DATE
AS BEGIN
WITH DATERANGE AS
(
SELECT DT =DATEADD(DD,0, #STARTDATE)
WHERE DATEADD(DD, 1, #STARTDATE) <= #ENDDATE
UNION ALL
SELECT DATEADD(DD, 1, DT)
FROM DATERANGE
WHERE DATEADD(DD, 1, DT) <= #ENDDATE
) SELECT * INTO cte_DATES
FROM DATERANGE
DECLARE #COLUMN varchar(max)
SELECT #COLUMN=ISNULL(#COLUMN+',','')+ '['+ CAST(CONVERT(DATE , T.DT) AS varchar) + ']' FROM cte_DATES T
DECLARE #Columns2 varchar(max)
SET #Columns2 = SUBSTRING((SELECT DISTINCT ',ISNULL(['+ CAST(CONVERT(DATE , DT)
as varchar )+'],'''') AS ['+ CAST(CONVERT(DATE , DT) as varchar )+']'
FROM cte_DATES GROUP BY dt FOR XML PATH('')),2,8000)
DECLARE #QUERY varchar(MAX)
SET #QUERY = 'SELECT P.EID, ENAME, ' + #Columns2 +', Wdays, Holidays, K.Present, (Wdays-(Holidays + K.Present))as Absent, (cast(((s.Salary/Wdays)*(k.present+Holidays)) as numeric(36,0))) as Salary FROM
(
SELECT A.EID, A.ENAME , B.DT AS DATE, (Case when cast(A.WorkTime as time) >
''00:00:00'' then ''P'' else ''Abs'' end) as worktime FROM TblAttendnce A
RIGHT OUTER JOIN cte_DATES B
ON A.EDATE=B.DT
) X
PIVOT
(
MIN([Worktime])
FOR [DATE] IN (' + #COLUMN + ')
) P
Cross apply (select Wdays, Holidays from dbo.fn_Fn1(''' + CAST(#STARTDATE AS VARCHAR(50)) + ''','''+ CAST(#ENDDATE as Varchar(50))+'''))H
Right Outer Join (select eid, COUNT(present) as present from Attendace.dbo.vwPayroll
where Edate between ''' + CAST(#STARTDATE AS VARCHAR(50)) + '''and'''+ CAST(#ENDDATE as Varchar(50))+'''
group by eid) as K on K.eid=p.EID
Right Outer Join ((select eid, salary from dbo.employeeMast))as s on S.eid=p.eid
WHERE ISNULL(ENAME,'''')<>''''
'
Exec (#QUERY)
DROP TABLE cte_DATES
END
Now the outcome is like this
i need to prepare a crystal report from this procedure, but due to dynamic column header name i am unable to do this.
My Query is how to make column name as 01, 02, 03 instead of 2018-04-01, 2018-04-02, 2018-04-03
i mean i want to rename column name as DD of dd/mm/yyyy
by this way i may able to reflect it in crystal report.

When I am developing a Crystal Report or training a client; I teach them either to rename to the data field in the SQL or stored procedure such date as 3 or Insert a Duplicate Detail line and use the OLD line for Development. Making the NEW Line a Comment Line.

Related

Ignore Sunday while generating student attendance report in SQL

This code gives me the attendance report between two dates passed as a parameter.
I will pass dates respective of the month selected from the C# code.
But I want to skip Sundays while generating the attendance report. How can I achieve this?
DECLARE #startdate date = '20180109';
DECLARE #enddate date = '20180112';
DECLARE #cols as varchar(2000);
DECLARE #query as varchar(MAX);
WITH cte (startdate)
AS
(SELECT
#startdate AS startdate
UNION ALL
SELECT
DATEADD(DAY, 1, startdate) AS startdate
FROM cte
WHERE startdate < #enddate
)
select c.startdate
into #tempDates
from cte c
SELECT
#cols = STUFF((SELECT DISTINCT
',' + QUOTENAME(CONVERT(CHAR(10),
startdate, 120))
FROM #tempDates
FOR XML PATH (''), TYPE)
.value('.', 'NVARCHAR(MAX)')
, 1, 1, '')
SET #query = 'SELECT RollNo,FirstName,LastName, ' + #cols + ' from
(
select S.RollNo,U.FirstName,U.LastName,
D.startdate,
convert(CHAR(10), startdate, 120) PivotDate
from #tempDates D,Attendance A, Student S, UserDetails U
where D.startdate = A.Date and A.EnrollmentNo=S.EnrollmentNo and A.EnrollmentNo=U.userID
) x
pivot
(
count(startdate)
for PivotDate in (' + #cols + ')
) p '
EXECUTE (#query)
drop table #tempDates
How about changing #TempDates?
select c.startdate
into #tempDates
from cte c
where datename(weekday, c.startdate) <> 'Sunday';
This assumes that your internationalization settings are set to "English".

How to create Temp Table with month columns based on date parameters?

I have a stored procedure that accepts two Dates. In my stored procedure, I need to create a temp table with the months in between the two dates as columns.
For example,
If the user passes in
1/1/2016 , 8/1/2016
I need a temp table with the columns:
January February March April May June July August
How could I create this type of temp table with columns created in this manner? With the columns being based on the two dates passed in?
The following script should get you started (and almost there):
declare #start_date DATE = '20160101'
declare #end_date DATE = '20160801'
;WITH CTE AS
(
SELECT #start_date AS cte_start_date, DATENAME(month, #start_date) AS Name,
CAST(' ALTER TABLE #myTemp ADD ' + DATENAME(month, #start_date) + ' INT ' + CHAR(13) + CHAR(10) AS VARCHAR(8000)) AS SqlStr
UNION ALL
SELECT DATEADD(MONTH, 1, cte_start_date), DATENAME(month, DATEADD(MONTH, 1, cte_start_date)) AS Name,
CAST(SqlStr + ' ALTER TABLE #myTemp ADD ' + DATENAME(month, DATEADD(MONTH, 1, cte_start_date)) + ' INT ' + CHAR(13) + CHAR(10) AS VARCHAR(8000))
FROM CTE
WHERE DATEADD(MONTH, 1, cte_start_date) <= #end_date
)
SELECT cte_start_date, Name, SqlStr
FROM CTE
Using a recursive-CTE it generates a loop between start and end date, and for each month it computes its string representation and also creates a alter script to add the columns to a temporary table.
The CTE computes the SQL script gradually, so that the final script is on the last line.
Try This ....
declare #start_date DATE = '20160101'
declare #end_date DATE = '20160801'
;WITH CTE AS
(
SELECT #start_date AS cte_start_date, DATENAME(month, #start_date) AS NAME , 0 AS Coun
UNION ALL
SELECT DATEADD(MONTH, 1, cte_start_date), DATENAME(month, DATEADD(MONTH, 1, cte_start_date)) AS NAME , 0 AS Coun
FROM CTE
WHERE DATEADD(MONTH, 1, cte_start_date) <= #end_date
)
SELECT Coun,Name
INTO #tmp1
FROM CTE
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT ',' + Name
from #tmp1
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT ' + #cols + ' from
(
select Coun,Name
from #tmp1
) x
pivot
(
MAX(Coun)
for Name in (' + #cols + ')
) p '
execute(#query);
DROP TABLE #tmp1
It Will Return OutPut Like your expected output .......

SQL how to select dates between 2 date parameters as columns in a stored procedure

I need to write a stored procedure that takes 2 date parameters, sums up some data for that date, and returns a row with the dates inbetween as columns.
Im not sure where to start.
Lets say my stored procedure looks like this:
spGetAccountBalanceByDay(DateTime startDate, DateTime endDate)
I would like the column name to be formatted like this: F_{0}{1}{2} where {0} = year, {1} = Month, and {2} = Day.
so for the date 13/12/2014, my column would be called f_2014_12_13. I have a datasource that has dynamic properties which match ( as the grid in question can be run for any date range )
So in the SQL stored procedure, I want to loop between the 2 dates, sum the account balance for each date, and put the data in the column for that day.
So my table would look something like this returned by the stored procedure:
Account Ref | F_2014_12_13 | F_2014_12_14 | F_2014_12_15
------------------------------------------
ABB001 100 150 0
These queries can return one or more rows, I just need to know what function In SQL i should be looking to use, I know its possible to select columns dynamically just not sure how to do it.
Any advice would be appreciated.
Combining a few things I have found across the internet this is the solution I have come up with:
DECLARE #Columns VARCHAR(MAX)
DECLARE #StartDate AS DATETIME
DECLARE #EndDate AS DATETIME
DECLARE #Query AS VARCHAR(MAX)
SET #StartDate = '01 Jan 2012'
SET #EndDate = '31 Mar 2012'
;WITH dateRange as
(
SELECT [Date] = DATEADD(dd, 1, DATEADD(dd, -1,#startDate))
WHERE DATEADD(dd, 1, #startDate) < DATEADD(dd, 1, #endDate)
UNION ALL
SELECT DATEADD(dd, 1, [Date])
FROM dateRange
WHERE DATEADD(dd, 1, [Date]) < DATEADD(dd, 1,#endDate)
)
SELECT #Columns = COALESCE(#Columns, '[') + CONVERT(VARCHAR, [Date], 111) + '],['
FROM dateRange
OPTION (maxrecursion 0)
--delete last two chars of string (the ending ',[') and store columns in variable
SET #Columns = SUBSTRING(#Columns, 1, LEN(#Columns)-2)
SELECT #Columns
SET #Query =
'
SELECT *
FROM
(
SELECT
[PLSupplierAccount].[SupplierAccountNumber],
[PLSupplierAccount].[SupplierAccountName],
[PLPostedSupplierTran].[DueDate],
[PLPostedSupplierTran].[GoodsValueInAccountCurrency] * [PLPostedSupplierTran].[DocumentToBaseCurrencyRate] AS [Value]
FROM [PLPostedSupplierTran]
INNER JOIN [PLSupplierAccount]
ON [PLSupplierAccount].[PLSupplierAccountID]
= [PLPostedSupplierTran].[PLSupplierAccountID]
WHERE [PLPostedSupplierTran].[DueDate]>= ''' + CONVERT(VARCHAR(50), #StartDate, 111) + ''' AND [PLPostedSupplierTran].[DueDate]<= ''' + CONVERT(VARCHAR(50), #EndDate, 111) + '''
) src
PIVOT
(
SUM([Value])
FOR src.[DueDate] IN (' + #Columns + ')
) AS PivotView
'
EXEC (#Query)

Getting null value in the Grand Total column in the Pivot Table in sql

I have the query which returning me the number of categories in one cloumn and other column are dynamic column they are giving me the the months between start date & end date and this column are returning me the amount of the categories sold on that month.
I want to add the Grand Total at the end of the row in the query
Here's My Query
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX),
#subtotal AS FLOAT,
#startdate as datetime,
#enddate as datetime
DECLARE #ColumnsRollup AS VARCHAR (MAX)
set #startdate = '1-Mar-2014'
set #enddate = '1-Aug-2014'
;with cte (StartDate, EndDate) as
(
select min(#startdate) StartDate, max(#enddate) EndDate
union all
select dateadd(mm, 1, StartDate), EndDate
from cte
where StartDate < EndDate
)
select StartDate
into #tempDates
from cte
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(convert(CHAR(10), StartDate, 120))
from #tempDates
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'') + ',[Total]'
SET #query = 'select ledger_name,
' + #cols + '
from
(
SELECT
CASE WHEN (GROUPING(ledger_name) = 1) THEN ''Grand Total''
ELSE ledger_name END AS ledger_name,
ISNULL(SUM(amount),0) Amount,
CASE WHEN (GROUPING(StartDate) = 1) THEN ''Total''
ELSE convert(CHAR(10), StartDate, 120) END StartDate
FROM #tempDates d
left join Rs_Ledger_Master AS LM on d.StartDate between '''+convert(varchar(10), #startdate, 120)+''' and '''+convert(varchar(10), #enddate, 120)+'''
LEFT OUTER JOIN RS_Payment_Master AS PM ON PM.ledger_code = LM.ledger_code and month(paid_date) = month(StartDate) and year(paid_date) = year(StartDate)
group by
ledger_name,StartDate WITH ROLLUP
) d
pivot
(
SUM(Amount)
for StartDate in (' + #cols + ')
) p
ORDER BY CASE WHEN ledger_name = ''Grand Total'' THEN 1 END'
execute sp_executesql #query;
drop table #tempDates
I think what you can do is, try to use the ROLLUP option in your inner query, which actually returns addtional row for the SUM(Amount), which you can call as Total and add this column to your column list.
Here is the change what I think you need to do
Add total column at the end of your column list
SET #cols= #cols + ',[Total]'
Add the rollup option to your inner query. Note that, the case statement is required to change the text as total for the row.
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX),
#subtotal AS FLOAT,
#startdate as datetime,
#enddate as datetime
DECLARE #ColumnsRollup AS VARCHAR (MAX)
set #startdate = '1-Mar-2014'
set #enddate = '1-Aug-2014'
;with cte (StartDate, EndDate) as
(
select min(#startdate) StartDate, max(#enddate) EndDate
union all
select dateadd(mm, 1, StartDate), EndDate
from cte
where StartDate < EndDate
)
select StartDate
into #tempDates
from cte
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(convert(CHAR(10), StartDate, 120))
from #tempDates
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'') + ',[Total]'
SET #query = 'select ledger_name,
' + #cols + '
from
(
SELECT
ledger_name,
ISNULL(SUM(amount),0) Amount,
CASE WHEN (GROUPING(StartDate) = 1) THEN ''Total''
ELSE convert(CHAR(10), StartDate, 120) END StartDate
FROM #tempDates d
left join Rs_Ledger_Master AS LM on d.StartDate between '''+convert(varchar(10), #startdate, 120)+''' and '''+convert(varchar(10), #enddate, 120)+'''
LEFT OUTER JOIN RS_Payment_Master AS PM ON PM.ledger_code = LM.ledger_code and month(paid_date) = month(StartDate) and year(paid_date) = year(StartDate)
group by
ledger_name,StartDate WITH ROLLUP
) d
pivot
(
SUM(Amount)
for StartDate in (' + #cols + ')
) p
WHERE ledger_name IS NOT NULL
UNION ALL
select ledger_name,
' + #cols + ' FROM
(SELECT ''Grand Total'' AS ledger_name,
ISNULL(SUM(amount),0) Amount,
CASE WHEN (GROUPING(StartDate) = 1) THEN ''Total''
ELSE convert(CHAR(10), StartDate, 120) END StartDate
FROM #tempDates d
left join Rs_Ledger_Master AS LM on d.StartDate between '''+convert(varchar(10), #startdate, 120)+''' and '''+convert(varchar(10), #enddate, 120)+'''
LEFT OUTER JOIN RS_Payment_Master AS PM ON PM.ledger_code = LM.ledger_code and month(paid_date) = month(StartDate) and year(paid_date) = year(StartDate)
group by StartDate WITH ROLLUP
) d
pivot
(
SUM(Amount)
for StartDate in (' + #cols + ')
) p
'
print #query
execute sp_executesql #query;
drop table #tempDates
You need additional union all to get the last summary row
You can refer the following article for using ROLLUP
http://technet.microsoft.com/en-us/library/ms189305(v=sql.90).aspx

Pivot In Values with dates?

At the end of my sql, I am using the following code. Is there any way of replacing the fixed strings [2011/07/14], [2011/07/16], etc, to GetDate() value?
PIVOT
(
count([AppointmentsBooked])
FOR [date] IN ([2011/07/14], [2011/07/16], [2011/07/17],[2011/07/18],[2011/07/21])
) as pivottable
Can you try to use BETWEEN and DATEADD in following manner:
DECLARE #dates TABLE(value DateTime)
INSERT INTO #dates VALUES
(GETDATE()),
('2011/07/9'),
('2011/07/17'),
('2011/07/18'),
('2011/07/21')
SELECT value FROM #dates
WHERE value BETWEEN GETDATE() AND DATEADD(day, 5, GETDATE())
You can create a string of all dates which is comma seperated with '[' and ']' before and after each date. assign this string to a string variable (#dates) and use the string spit method to split all dates inside the pivot query.
this question was posted about a year ago. i don't care. i have some code that might be exactly what the OP wanted.... i'm sure he'll never come back and chose an answer but still.... all i want to do is count the records by month with a pivot for a few tables and ultimately compare the number of records for each month for each table. however... in this code there is only one table (rt_taco_15m) but that doesn't matter. i just haven't written the rest to completely fit my needs. but i think it fits the needs of the OP or at least gets him on a good start.... if he truly has been waiting a year on this problem. lol.
if object_id('tempdb..#temp') is not null drop table #temp
if object_id('tempdb..#temp2') is not null drop table #temp2
if object_id('tempdb..#temp3') is not null drop table #temp3
declare #start_date as datetime
set #start_date = cast('1-1-2012' as datetime)
declare #end_date as datetime
set #end_date = cast('9-1-2012' as datetime)
;with cte as (
select #start_date as [start],
dateadd(month, 1, #start_date) as [end]
union all
select dateadd(month, 1, [start]) as [start],
dateadd(month, 1, dateadd(month, 1, [start])) as [end]
from cte
where dateadd(month, 1, [start]) <= #end_date
)
(select 'rt_taco_15m' as table_name,
convert(varchar(10), [start], 101) as [start],
convert(varchar(10), [end], 101) as [end],
datename(month, [start]) as month_name,
cast([start] as integer) as orderby,
count(taco.taco_record_id) as [range_count]
into #temp
from cte
left outer join rt_taco_15m as taco
on taco.period >= cte.[start] and
taco.period < cte.[end]
group by cte.[start], cte.[end])
select table_name as table_name,
convert(varchar(10), getdate(), 101) as [start],
convert(varchar(10), getdate(), 101) as [end],
'Total' as month_name,
cast(dateadd(month,2,#end_date) as integer) as orderby,
range_sum as [range_count]
into #temp2
from (select table_name, sum([range_count]) as range_sum
from #temp group by table_name) as summed_up
select *
into #temp3
from (select * from #temp
union all
select * from #temp2) as x
order by orderby
select * from #temp3
declare #cols nvarchar(2000)
select #cols = stuff(
(select '],[' + month_name
from #temp3
order by orderby
for xml path('') )
, 1, 2, '') + ']'
print #cols
if object_id('tempdb..#temp2') is not null drop table #temp2
declare #query varchar(max)
set #query = N'
select table_name, ' + #cols + N'
from (select table_name, month_name, range_count
from #temp3) p
pivot ( sum(range_count) for month_name in ( '+ #cols +' ) ) as pvt'
execute(#query