How do you find the total sales count for a salesperson by weekly, monthly and yearly ?
SELECT AdjusterName,
SUM(CASE WHEN TaskDate >= DATEADD(WEEK, DATEDIFF(WEEK, 0, SYSDATETIME()), 0)
AND TaskDate < DATEADD(WEEK, DATEDIFF(WEEK, 0, SYSDATETIME()) + 1, 0)
THEN 1 ELSE 0 END) AS WTD,
sum(case when MONTH(TaskDate) = MONTH(GetDate()) then 1 else 0 end ) as MTD,
sum(case when year(TaskDate) = year(GetDate()) then 1 else 0 end ) as YTD
FROM cte
GROUP BY AdjusterName
for example:-
name WTD MTD YTD
SalesPersnA 2 5 10
Sample Data
ID SalesPerson NAME TaskDate TaskAge DocumentType TaskStatus OverdueCheck
2000378 Willy Akron FNOL Supervisor Team 1 2015-02-04 1258 Claim.Reassigned.File.Text Completed WithinSLA
2000378 Amanda Akron FNOL Supervisor Team 1 2015-02-04 1258 ClaimLifecycle.Open.RD.Text Completed WithinSLA
2000388 Amanda Akron FNOL Supervisor Team 1 2016-08-06 709 ClaimLifecycle.Open.RD.Text Completed WithinSLA
2000388 Willy Akron FNOL Supervisor Team 1 2016-08-06 709 Claim.Reassigned.File.Text Completed WithinSLA
2000388 Schutz Akron FNOL Supervisor Team 1 2016-09-21 663 ISO.Failure.Diary.Text: Completed WithinSLA
2000388 Stephannie Akron FNOL Supervisor Team 1 2016-09-26 658 Claim.Reassigned.File.Text Completed WithinSLA
Count ignore nulls, so you could use a count call on top of a case expression for the last week and month. The condition on the year could be expressed in the where clause:
SELECT SalesPerson,
COUNT(CASE DATEDIFF(WEEK, TaskDate, GETDATE()) = 0 THEN 1 END) AS WTD,
COUNT(CASE DATEDIFF(MONTH, TaskDate, GETDATE()) = 0 THEN 1 END) AS MTD,
COUNT(*)
FROM mytable
WHERE DATEDIFF(YEAR, TaskDate, GETDATE()) = 0
GROUP BY SalesPerson
If you want results for year, month, week in columns you can achieve with window functions:
declare #test table (ID int, SalesPerson nvarchar(100), [Name] nvarchar(100), TaskDate date, TaskAge int, DocumentType nvarchar(max), TaskStatus nvarchar(20), OverdueCheck nvarchar(20))
insert into #test values
(2000378, 'Willy' , 'Akron FNOL Supervisor Team 1', '2015-02-04', 1258, 'Claim.Reassigned.File.Text ', 'Completed', 'WithinSLA')
, (2000378, 'Amanda' , 'Akron FNOL Supervisor Team 1', '2015-02-04', 1258, 'ClaimLifecycle.Open.RD.Text', 'Completed', 'WithinSLA')
, (2000388, 'Amanda' , 'Akron FNOL Supervisor Team 1', '2016-08-06', 709 , 'ClaimLifecycle.Open.RD.Text', 'Completed', 'WithinSLA')
, (2000388, 'Willy' , 'Akron FNOL Supervisor Team 1', '2016-08-06', 709 , 'Claim.Reassigned.File.Text ', 'Completed', 'WithinSLA')
, (2000388, 'Schutz' , 'Akron FNOL Supervisor Team 1', '2016-09-21', 663 , 'ISO.Failure.Diary.Text: ', 'Completed', 'WithinSLA')
, (2000388, 'Stephannie', 'Akron FNOL Supervisor Team 1', '2016-09-26', 658 , 'Claim.Reassigned.File.Text ', 'Completed', 'WithinSLA')
select SalesPerson
, Year(TaskDate) as [Year]
, month(taskdate) as [Month]
, DATEPART( wk, taskdate) as [Week]
, count(*) over (Partition by salesperson, Year(taskdate)) as [YearCount]
, count(*) over (Partition by salesperson, Year(taskdate), Month(taskdate)) as [MonthCount]
, count(*) over (Partition by salesperson, Year(taskdate), DATEPART( wk, taskdate)) as [WeekCount]
from #test
This worked for me! Thank you all for your suggestions and time.
select AdjusterName, NAME,
sum(case when DATEPART( wk,TaskDate) = DATEPART ( wk, getdate()) and YEAR(taskDate) = 2018 then 1 else 0 end ) as WTD,
sum(case when DATEPART (m, TaskDate ) = DATEPART ( m, getdate()) and YEAR(taskDate) = 2018 then 1 else 0 end ) as MTD,
sum(case when DATEPART (YEAR, TaskDate) = DATEPART ( YEAR, getdate()) and YEAR(taskDate) = 2018 then 1 else 0 end ) as YTD
from cte
group by AdjusterName,NAME
Related
I have the following table, like:
woker
date
amount
jeff
04-04-2022
4.00
jeff
04-05-2022
2.00
jeff
04-08-2022
3.50
dave
04-04-2022
1.00
dave
04-07-2022
6.50
It contains the date and the amount of hours worked by a worker.
Now I want to create a table like the following with a select to show hours per weekday. The column "count" should represent the amount of days where the worker has hours. The column "sum" should sum the hours for this week.
So the final result should be like this:
worker
mon
tue
wed
thu
fri
sat
sun
count
sum
jeff
4.00
2.00
null
null
3.50
null
null
3
9.50
dave
1.00
null
null
6.50
null
null
null
2
7.50
My statement so far is:
SELECT worker,
CASE WHEN DATEPART(weekday,date) = 1 THEN amount END AS mon,
CASE WHEN DATEPART(weekday,date) = 2 THEN amount END AS tue,
CASE WHEN DATEPART(weekday,date) = 3 THEN amount END AS wed,
CASE WHEN DATEPART(weekday,date) = 4 THEN amount END AS thu,
CASE WHEN DATEPART(weekday,date) = 5 THEN amount END AS fri,
CASE WHEN DATEPART(weekday,date) = 6 THEN amount END AS sat,
CASE WHEN DATEPART(weekday,date) = 7 THEN amount END AS sun
FROM table
So now I need help to get the last two columns. Can anybody explain, how to sum up / count values over multiple columns withi one entry?
Thank you.
We use the function SUM so as to be able to agregate the different lines. We add the week number in the SELECT and the GROUP BY so as to separate the weeks and know which week of the year we are looking at. We could also add the year if the same table will be used for long enough.
SET DATEFIRST 1;
SELECT
DATEPART(week, date) AS "week",
worker,
CASE WHEN DATEPART(weekday,date) = 1 THEN amount END ) AS mon,
SUM( CASE WHEN DATEPART(weekday,date) = 2 THEN amount END ) AS tue,
SUM( CASE WHEN DATEPART(weekday,date) = 3 THEN amount END ) AS wed,
SUM( CASE WHEN DATEPART(weekday,date) = 4 THEN amount END ) AS thu,
SUM( CASE WHEN DATEPART(weekday,date) = 5 THEN amount END ) AS fri,
SUM( CASE WHEN DATEPART(weekday,date) = 6 THEN amount END ) AS sat,
SUM( CASE WHEN DATEPART(weekday,date) = 7 THEN amount END ) AS sun,
COUNT(DISTINCT DATEPART(weekday,date) ) AS "count",
amount AS "sum"
FROM table
GROUP BY
DATEPART(week, date),
worker
ORDER BY
DATEPART(week, date),
worker;
Conditional aggregation is an option (don't forget to set the first day of the week using SET DATEFIRST):
SET DATEFIRST 1
SELECT
worker,
SUM(CASE WHEN DATEPART(weekday, date) = 1 THEN amount END) AS mon,
SUM(CASE WHEN DATEPART(weekday, date) = 2 THEN amount END) AS tue,
SUM(CASE WHEN DATEPART(weekday, date) = 3 THEN amount END) AS wed,
SUM(CASE WHEN DATEPART(weekday, date) = 4 THEN amount END) AS thu,
SUM(CASE WHEN DATEPART(weekday, date) = 5 THEN amount END) AS fri,
SUM(CASE WHEN DATEPART(weekday, date) = 6 THEN amount END) AS sat,
SUM(CASE WHEN DATEPART(weekday, date) = 7 THEN amount END) AS sun,
COUNT(DISTINCT DATEPART(weekday, date)) AS [count],
SUM(amount) AS [sum]
FROM (VALUES
('jeff', CONVERT(date, '20220404'), 4.00),
('jeff', CONVERT(date, '20220405'), 2.00),
('jeff', CONVERT(date, '20220408'), 3.50),
('dave', CONVERT(date, '20220404'), 1.00),
('dave', CONVERT(date, '20220407'), 6.50)
) t (worker, date, amount)
GROUP BY worker
ORDER BY worker
Result:
worker
mon
tue
wed
thu
fri
sat
sun
count
sum
dave
1.00
6.50
2
7.50
jeff
4.00
2.00
3.50
3
9.50
If you want to summarize the input data based on time interval, you need a different statement:
SET DATEFIRST 1
SELECT
worker,
--DATEPART(week, date) AS week,
DATEPART(month, date) AS month,
SUM(CASE WHEN DATEPART(weekday, date) = 1 THEN amount END) AS mon,
SUM(CASE WHEN DATEPART(weekday, date) = 2 THEN amount END) AS tue,
SUM(CASE WHEN DATEPART(weekday, date) = 3 THEN amount END) AS wed,
SUM(CASE WHEN DATEPART(weekday, date) = 4 THEN amount END) AS thu,
SUM(CASE WHEN DATEPART(weekday, date) = 5 THEN amount END) AS fri,
SUM(CASE WHEN DATEPART(weekday, date) = 6 THEN amount END) AS sat,
SUM(CASE WHEN DATEPART(weekday, date) = 7 THEN amount END) AS sun,
COUNT(DISTINCT DATEPART(weekday, date)) AS [count],
SUM(amount) AS [sum]
FROM (VALUES
('jeff', CONVERT(date, '20220404'), 4.00),
('jeff', CONVERT(date, '20220405'), 2.00),
('jeff', CONVERT(date, '20220408'), 3.50),
('dave', CONVERT(date, '20220404'), 1.00),
('dave', CONVERT(date, '20220407'), 6.50)
) t (worker, date, amount)
--GROUP BY worker, DATEPART(week, date)
--ORDER BY worker, DATEPART(week, date)
GROUP BY worker, DATEPART(month, date)
ORDER BY worker, DATEPART(month, date)
Instead om doing alot aggregates, cases and dateparts I would do a pivot table out of it like below. (Note that my days-weekdays ref may not be the same as yours)
Test data:
declare #tbl table (worker varchar(20), [date] date, amount dec(5,2))
INSERT INTO #tbl
SELECT 'jeff', '04-04-2022', 4.00
UNION SELECT 'jeff', '05-04-2022', 2.00
UNION SELECT 'jeff', '08-04-2022', 3.50
UNION SELECT 'dave', '04-04-2022', 1.00
UNION SELECT 'dave', '07-04-2022', 6.50
The actual code:
SELECT
worker
, [1] as sun
, [2] as mon
, [3] as tue
, [4] as wed
, [5] as thu
, [6] as fri
, [7] as sat
, [count]
, [sum]
FROM (select
worker
, amount
, datepart(weekday, t.[date]) dp
, COUNT(amount) OVER( partition by worker) as [count]
, SUM(amount) OVER( partition by worker) as [sum]
from #tbl t
) p
PIVOT(
SUM(amount)
FOR dp in ([1], [2], [3], [4], [5], [6], [7])
) piv
I'm learning about PIVOT function and I want to try it in my DB, in the table DDOT I have events (rows) made by users during X month Y year in the YYYYMM format.
id_ev iddate id_user ...
------------------------
1 201901 321
2 201902 654
3 201903 987
4 201901 321
5 201903 987
I'm basing my query on the MS Documentation and I'm not getting errors but I'm not able to fill it with the SUM of those unique events (users). In simple words I want to know how many users (unique) checked up each month (x axis) in the year (y axis). However, I'm getting NULL as result
YYYY jan feb mar
----------------------------
2019 NULL NULL NULL
I'm expecting a full table with what I mentionted before.
YYYY jan feb mar
----------------------------
2019 2 1 1
In the code I've tried with different aggregate functions but this block is the closest to a result from SQL.
CREATE TABLE ddot
(
id_ev int NOT NULL ,
iddate int NOT NULL ,
id_user int NOT NULL
);
INSERT INTO DDOT
(
[id_ev], [iddate], [id_user]
)
VALUES
(
1, 201901, 321
),
(
2, 201902, 654
),
(
3, 201903, 987
),
(
4, 201901, 321
),
(
5, 201903, 987
)
GO
SELECT *
FROM (
SELECT COUNT(DISTINCT id_user) [TOT],
DATENAME(YEAR, CAST(iddate+'01' AS DATETIME)) [YYYY], --concat iddate 01 to get full date
DATENAME(MONTH, CAST(iddate+'01' AS DATETIME)) [MMM]
FROM DDOT
GROUP BY DATENAME(YEAR, CAST(iddate+'01' AS DATETIME)),
DATENAME(MONTH, CAST(iddate+'01' AS DATETIME))
) AS DOT_COUNT
PIVOT(
SUM([TOT])
FOR MMM IN (jan, feb, mar)
) AS PVT
Ideally you should be using an actual date in the iddate column, and not a string (number?). We can workaround this using the string functions:
SELECT
CONVERT(varchar(4), LEFT(iddate, 4)) AS YYYY,
COUNT(CASE WHEN CONVERT(varchar(2), RIGHT(iddate, 2)) = '01' THEN 1 END) AS jan,
COUNT(CASE WHEN CONVERT(varchar(2), RIGHT(iddate, 2)) = '02' THEN 1 END) AS feb,
COUNT(CASE WHEN CONVERT(varchar(2), RIGHT(iddate, 2)) = '03' THEN 1 END) AS mar,
...
FROM DDOT
GROUP BY
CONVERT(varchar(4), LEFT(iddate, 4));
Note that if the iddate column already be text, then we can remove all the ugly calls to CONVERT above:
SELECT
LEFT(iddate, 4) AS YYYY,
COUNT(CASE WHEN RIGHT(iddate, 2) = '01' THEN 1 END) AS jan,
COUNT(CASE WHEN RIGHT(iddate, 2) = '02' THEN 1 END) AS feb,
COUNT(CASE WHEN RIGHT(iddate, 2) = '03' THEN 1 END) AS mar,
...
FROM DDOT
GROUP BY
LEFT(iddate, 4);
I'm trying to pivot on multiple columns and I'm using SQL Server 2014, however, I cannot figure out how to do that. Here's what I've tried so far:
DECLARE #Table TABLE (
Name NVARCHAR(MAX),
TypeId INT,
TotalOrders INT,
GrandTotal MONEY
)
INSERT INTO #Table
(Name, TypeId, TotalOrders, GrandTotal)
VALUES
('This Month', 1, 10, 1),
('This Month', 2, 5, 7),
('This Week', 1, 8, 3),
('Last Week', 1, 8, 12),
('Yesterday', 1, 10, 1),
('Yesterday', 2, 1, 5)
Which produces the following result:
Name TypeId TotalOrders GrandTotal
-------------------------------- ----------- ----------- ---------------------
This Month 1 10 1.00
This Month 2 5 7.00
This Week 1 8 3.00
Last Week 1 8 12.00
Yesterday 1 10 1.00
Yesterday 2 1 5.00
To bring those rows into columns, I've tried this:
SELECT
TypeId,
ISNULL([Yesterday], 0) AS YesterdayTotalOrders,
ISNULL([This Week], 0) AS ThisWeekTotalOrders,
ISNULL([Last Week], 0) AS LastWeekTotalOrders,
ISNULL([This Month], 0) AS ThisMonthTotalOrders
FROM
(SELECT Name, TypeId, TotalOrders FROM #Table) AS src
PIVOT (
SUM(TotalOrders) FOR Name IN (
[Yesterday],
[This Week],
[Last Week],
[This Month]
)
) AS p1
Which produces the following result set:
TypeId YesterdayTotalOrders ThisWeekTotalOrders LastWeekTotalOrders ThisMonthTotalOrders
----------- -------------------- ------------------- ------------------- --------------------
1 10 8 8 10
2 1 0 0 5
Now, I need to have few other columns for GrandTotal such as YesterdayGrandTotal, ThisWeekGrandTotal, and so on and so forth but I can't figure out how to achieve this.
Any help would be highly appreciated.
UPDATE#1: Here's the expected result set:
TypeId YesterdayTotalOrders ThisWeekTotalOrders LastWeekTotalOrders ThisMonthTotalOrders YesterdayGrandTotal ThisWeekGrandTotal LastWeekGrandTotal ThisMonthGrandTotal
----------- -------------------- ------------------- ------------------- -------------------- --------------------- --------------------- --------------------- ---------------------
1 10 8 8 10 1.00 3.00 12.00 1.00
2 1 0 0 5 5.00 0.00 0.00 7.00
Conditional aggregation may be a solution:
select typeID,
SUM(case when name = 'Yesterday' then totalOrders else 0 end) as YesterdayTotalOrders,
SUM(case when name = 'This Week' then totalOrders else 0 end) as ThisWeekTotalOrders,
SUM(case when name = 'Last Week' then totalOrders else 0 end) as LastWeekTotalOrders,
SUM(case when name = 'This Month' then totalOrders else 0 end) as ThisMonthTotalOrders,
SUM(case when name = 'Yesterday' then GrandTotal else 0 end) as YesterdayGrandTotal,
SUM(case when name = 'This Week' then GrandTotal else 0 end) as ThisWeekGrandTotal,
SUM(case when name = 'Last Week' then GrandTotal else 0 end) as LastWeekGrandTotal,
SUM(case when name = 'This Month' then GrandTotal else 0 end) as ThisMonthGrandTotal
from #table
group by typeID
or, you can use the CROSS APPLY and PIVOT like this
SELECT
TypeId,
ISNULL([Yesterday], 0) AS YesterdayTotalOrders,
ISNULL([This Week], 0) AS ThisWeekTotalOrders,
ISNULL([Last Week], 0) AS LastWeekTotalOrders,
ISNULL([This Month], 0) AS ThisMonthTotalOrders,
ISNULL([grant Yesterday], 0) AS YesterdayGrandTotal,
ISNULL([grant This Week], 0) AS ThisWeekGrandTotal,
ISNULL([grant Last Week], 0) AS LastWeekGrandTotal,
ISNULL([grant This Month], 0) AS ThisMonthGrandTotal
FROM
(
SELECT t.*
FROM #Table
CROSS APPLY (values(Name, TypeId, TotalOrders),
('grant ' + Name, TypeId, GrandTotal))
t(Name, TypeId, TotalOrders)
) AS src
PIVOT (
SUM(TotalOrders) FOR Name IN (
[Yesterday],
[This Week],
[Last Week],
[This Month],
[grant Yesterday],
[grant This Week],
[grant Last Week],
[grant This Month]
)
) AS p1
demo
Both solutions will scan the input table just once and they have a very similar query plan. Both solutions are better than JOIN of two pivots (the solution that I have originally provided) since two pivots need to scan the input table twice.
You could also use of CTE by separating your pivots.. P1 for TotalOrders & P2 for GrandTotal
;WITH CTE AS
(
SELECT
P1.TypeId,
ISNULL(P1.[Yesterday], 0) AS YesterdayTotalOrders,
ISNULL(P1.[This Week], 0) AS ThisWeekTotalOrders,
ISNULL(P1.[Last Week], 0) AS LastWeekTotalOrders,
ISNULL(P1.[This Month], 0) AS ThisMonthTotalOrders
FROM
(SELECT Name, TypeId, TotalOrders FROM #Table) AS src
PIVOT (SUM(TotalOrders) FOR src.Name IN (
[Yesterday],
[This Week],
[Last Week],
[This Month])) AS P1
), CTE1 AS
(
SELECT
P1.TypeId,
ISNULL(P1.[Yesterday], 0) AS YesterdayGrandTotal,
ISNULL(P1.[This Week], 0) AS ThisWeekTGrandTotal,
ISNULL(P1.[Last Week], 0) AS LastWeekGrandTotal,
ISNULL(P1.[This Month], 0) AS ThisMonthGrandTotal
FROM
(SELECT Name, TypeId, GrandTotal FROM #Table) AS src
PIVOT (SUM(GrandTotal) FOR src.Name IN (
[Yesterday],
[This Week],
[Last Week],
[This Month])) AS P1
)
SELECT C.TypeId , C.YesterdayTotalOrders, C.ThisWeekTotalOrders, C.LastWeekTotalOrders, C.ThisMonthTotalOrders , C1.YesterdayGrandTotal , C1.ThisWeekTGrandTotal ,C1.LastWeekGrandTotal , C1.ThisMonthGrandTotal FROM CTE C
INNER JOIN CTE1 C1 ON C1.TypeId = C.TypeId
Result :
TypeId YesterdayTotalOrders ThisWeekTotalOrders LastWeekTotalOrders ThisMonthTotalOrders YesterdayGrandTotal ThisWeekGrandTotal LastWeekGrandTotal ThisMonthGrandTotal
----------- -------------------- ------------------- ------------------- -------------------- --------------------- --------------------- --------------------- ---------------------
1 10 8 8 10 1.00 3.00 12.00 1.00
2 1 0 0 5 5.00 0.00 0.00 7.00
IN oracle i would do something like tihs. it works fine for me
select * from (
SELECT Name, TypeId,TotalOrders
--hier
,GrandTotal
FROM test_b )
PIVOT ( SUM(TotalOrders)TotalOrders,
--hier
SUM(grandtotal) grandtotal FOR Name IN
('Yesterday'Yesterday,'This Week'ThisWeek,'Last Week'LastWeek,'This
Month'ThisMonth )
) ;
so try this in sql server
SELECT *
/* TypeId,
ISNULL([Yesterday], 0) AS YesterdayTotalOrders,
ISNULL([This Week], 0) AS ThisWeekTotalOrders,
ISNULL([Last Week], 0) AS LastWeekTotalOrders,
ISNULL([This Month], 0) AS ThisMonthTotalOrders*/
FROM
(SELECT Name, TypeId, TotalOrders
,grandtotal
FROM #Table) AS src
PIVOT (
SUM(TotalOrders)TotalOrders, SUM(grandtotal)grandtotal FOR Name IN (
[Yesterday]Yesterday,
[This Week]ThisWeek,
[Last Week]LastWeek,
[This Month]ThisMonth
)
) AS p1
I have table1 in this data is
ID Name StartDate EndDate
1 Paris 2014-02-01 00:00:00.000 2014-02-28 23:59:59.000
2 UK 2014-02-01 00:00:00.000 2014-02-28 23:59:59.000
3 France 2014-02-01 00:00:00.000 2014-02-28 23:59:59.000
and sp is
ALTER procedure [dbo].[spdata]
#fromdate datetime,
#todate datetime,
#Region varchar(50)
as
Select (Select Sum(Convert(int,SF)) from RVU inner dbo.VI vh on RVU.FID = vh.FID WHERE vh.No = Q.No and ID in (
Select ID from RU WHERE CAST(StartDate as date)>= CAST(#fromdate as date) and CAST(EndDate as date)<= CAST(#todate as date)
)) as SF
from (
Select
S.Name,
S.No,
SUM(Case when s.Vme='Car' then total else 0 end) as CAR,
SUM(Case when s.Vme='Tin' then total else 0 end) as Tin,
SUM(Case when s.Vme='Cake' then total else 0 end) as Cake,
SUM(Case when s.Vme='Flow' then total else 0 end) as Flow,
SUM(Case when s.Vme='Unit' then total else 0 end) as Unit,
SUM(total) total ,
MAX(S.Speed) Speed
from (
Select vh.Name as Name,vh.No as No,VV.Vame,count(VV.Vme) as total, RV.SF as MA,
RV.Speed from VVU VV inner join RVU RV on VV.MID=RV.ID inner join RU RU on RV.ID=RU.ID
left join dbo.VI vh on RV.FID = vh.FID WHERE CAST(RU.StartDate as date)>= CAST(#fromdate as date) and CAST(RU.EndDate as date)<= CAST(#todate as date) and
RU.Name_C= #Name_C AND Vme <> '' Group By vh.Name, vh.No, VV.Vme, RV.SF,
RV.Speed ) S GROUP BY s.RegNo, s.Name) Q
from that sp when i enter parameters DATA IS
[spdata] '2016-07-01 00:00:00.000', '2016-07-31 23:59:59.000', 'pARIS'
Name No CAR Tin Cake Flow Unit total Speed SF
John 412 0 0 12 0 5 17 82 60
Mike 48 2 1 5 1 3 9 160 464
ACNme 438 0 1 5 2 3 11 10 264
XYZ 248 0 1 5 3 3 12 60 244
now i want when i change time '2016-07-01 00:00:00.000', '2016-07-31 23:59:59.000',
like this
'2016-07-01 02:02:00.000', '2016-07-31 12:59:59.000',
then records also reflect on this time means according to date plus time data will be display
Don't cast your StartDate , EndDate , #fromdate , #todate as Date.
`Alter procedure [dbo].[spdata]
#fromdate datetime,
#todate datetime,
#Region varchar(50)
as
Select (Select Sum(Convert(int,SF)) from RVU inner dbo.VI vh on RVU.FID = vh.FID WHERE vh.No = Q.No and ID in (
Select ID from RU WHERE StartDate >= #fromdate and EndDate <=#todate
)) as SF
from (
Select
S.Name,
S.No,
SUM(Case when s.Vme='Car' then total else 0 end) as CAR,
SUM(Case when s.Vme='Tin' then total else 0 end) as Tin,
SUM(Case when s.Vme='Cake' then total else 0 end) as Cake,
SUM(Case when s.Vme='Flow' then total else 0 end) as Flow,
SUM(Case when s.Vme='Unit' then total else 0 end) as Unit,
SUM(total) total ,
MAX(S.Speed) Speed
from (
Select vh.Name as Name,vh.No as No,VV.Vame,count(VV.Vme) as total, RV.SF as MA,
RV.Speed from VVU VV inner join RVU RV on VV.MID=RV.ID inner join RU RU on RV.ID=RU.ID
left join dbo.VI vh on RV.FID = vh.FID WHERE RU.StartDate >= #fromdate and RU.EndDate <= #todate and
RU.Name_C= #Name_C AND Vme <> '' Group By vh.Name, vh.No, VV.Vme, RV.SF,
RV.Speed
) S GROUP BY s.RegNo, s.Name) Q`
I have a table with following fields
Status, branch, reason code description, year, month, day, count
I am trying to get a report like this for each branch:
Reason code desc.,July,August,sept.,October.,nov.,Dec.,Total,% of Total
Reason 1. 4. 6. 2. 5. 0. 2. 19 79.1
Reason 2. 1 0. 2. 1. 1. 0 5. 20.9
--------------------------
5. 6. 4. 6. 1. 2. 24 100.0
Assuming that your database is Oracle the query can be:
select RCMonth.*, RCTotal.Total, round(RCTotal.Total*100/Total.Total, 2) "Total%"
from
(
select reasoncode , to_char(createdon,'Mon') mon
from rc_report
where createdon > sysdate - 180
union all
select 'Sum' , to_char(createdon,'Mon') mon
from rc_report
where createdon > sysdate - 180
) pivot
( count(*)
for mon in ('Aug', 'Sep', 'Oct', 'Nov', 'Dec', 'Jan')
) RCMonth
join ( select count(*) Total,
reasoncode
from rc_report
where createdon > sysdate - 180
group by reasoncode
union all
select count(*) Total,
'Sum'
from rc_report
where createdon > sysdate - 180
) RCTotal
on RCTotal.ReasonCode = RCMonth.ReasonCode
cross join (
select count(*) Total
from rc_report
where createdon > sysdate - 180 ) Total
order by RCMonth.ReasonCode
Sample result is:
Row# REASONCODE 'Aug' 'Sep' 'Oct' 'Nov' 'Dec' 'Jan' TOTAL Total%
1 Reason1 2 2 0 3 2 0 9 81.82
2 Reason2 0 1 0 1 0 0 2 18.18
3 Sum 2 3 0 4 2 0 11 100
Table definition is :
create table rc_report
(reasoncode varchar2(20),
createdon date)
And also version for SQL Server in SQL Fiddle
It's only a little bit different.
select RCMonth.*, RCTotal.Total, round( cast ( RCTotal.Total as decimal) *100 /Total.Total,2) "Total%"
from
(
select reasoncode, [Aug], [Sep], [Oct], [Nov], [Dec], [Jan] from (
select reasoncode , left( datename(Month,createdon),3) mon
from rc_report
where createdon >= DATEADD(MONTH, -6, GETDATE())
union all
select 'Sum' , left( datename(Month, createdon),3) mon
from rc_report
where createdon >= DATEADD(MONTH, -6, GETDATE())
) Source
pivot
( count(Source.mon)
for mon in ([Aug], [Sep], [Oct], [Nov], [Dec], [Jan])
) as PivotTable
) RCMonth
join ( select count(*) Total,
reasoncode
from rc_report
where createdon >= DATEADD(MONTH, -6, GETDATE())
group by reasoncode
union all
select count(*) Total,
'Sum'
from rc_report
where createdon >= DATEADD(MONTH, -6, GETDATE())
) RCTotal
on RCTotal.ReasonCode = RCMonth.ReasonCode
cross join (
select count(*) Total
from rc_report
where createdon >= DATEADD(MONTH, -6, GETDATE()) ) Total
order by RCMonth.ReasonCode