SELECT * FROM (
SELECT YEAR(CreateDate) [Year], MONTH(CreateDate) [Month], DATENAME(MONTH,CreateDate) [Month Name],COUNT(id) [Total],
CASE
WHEN PaymentStatus = 1 THEN 'Pending'
WHEN PaymentStatus = 2 THEN 'Commited'
WHEN PaymentStatus = 3 THEN 'Confirmed'
WHEN PaymentStatus = 4 THEN 'Canceled'
WHEN PaymentStatus = 5 THEN 'Failed'
ELSE ''
END AS PaymentStatus,count(ID) as counts
FROM [dbo].[BankPaymentRequest]
GROUP BY YEAR(CreateDate), MONTH(CreateDate), DATENAME(MONTH, CreateDate), PaymentStatus) as asd
PIVOT( SUM(counts)
FOR PaymentStatus IN ([Pending],[Commited],[Confirmed],[Canceled],[Failed])) AS MNamePivot
I want Year-Month wise data from this query with respective [Pending],[Commited],[Confirmed],[Canceled],[Failed] transaction count. Basically i want Month wise Transaction count for Pending,Commited,Confirmed,Canceled and Failed.
I am using Sql Server 2016
Now i am getting exact data but Months are listed twice or thrice.
I want data like below format
Year Month Total Pending Commited Confirmed Canceled Failed
2016 Jan 34 1 4 63 840 157
2016 Feb 34 8 4 62 8 15
2016 Mar 65 1 4 63 840 157
2016 Dec 56 8 4 62 8 15
2017 Jan 78 1 4 63 840 157
2017 Feb 89 8 4 62 8 15
2017 Mar 67 1 4 63 840 157
2017 Dec 8 4 62 8 15 345
Please help me for such query or any alternative query.
You could try putting your existing query inside of a Common Table Expression and then GROUP BY the year and month while summing the numbers.
WITH preselect AS
(
SELECT * FROM (
SELECT YEAR(CreateDate) [Year], MONTH(CreateDate) [Month], DATENAME(MONTH,CreateDate) [Month Name],COUNT(id) [Total],
CASE
WHEN PaymentStatus = 1 THEN 'Pending'
WHEN PaymentStatus = 2 THEN 'Commited'
WHEN PaymentStatus = 3 THEN 'Confirmed'
WHEN PaymentStatus = 4 THEN 'Canceled'
WHEN PaymentStatus = 5 THEN 'Failed'
ELSE ''
END AS PaymentStatus,count(ID) as counts
FROM [dbo].[BankPaymentRequest]
GROUP BY YEAR(CreateDate), MONTH(CreateDate), DATENAME(MONTH, CreateDate), PaymentStatus) as asd
PIVOT( SUM(counts)
FOR PaymentStatus IN ([Pending],[Commited],[Confirmed],[Canceled],[Failed])) AS MNamePivot
)
SELECT [YEAR],[MONTH],SUM(TOTAL)'TOTAL',SUM(Pending)'Pending'
,SUM(Commited)'Commited',SUM(Confirmed)'Confirmed'
,SUM(Canceled)'Canceled',SUM(Failed)'Failed'
FROM preselect
GROUP BY [YEAR],[MONTH]
Related
I've the following dataset:
System_Name Description Month Year Value_used YTD
APP01 PC A 4 2016 93 -
APP01 PC A 5 2016 90 1
APP01 PC A 6 2016 97 1
APP01 PC A 7 2016 82 -1
APP01 PC A 8 2016 99 1
CCD12 PC B 4 2016 81 -
CCD12 PC B 5 2016 83 1
CCD12 PC B 6 2016 83 0
CCD12 PC B 7 2016 87 1
CCD12 PC B 8 2016 88 1
This dataset is result from the following query:
SELECT *,
CASE WHEN Collect_Usage > PreviousQuota THEN 1
WHEN Collect_Usage = PreviousQuota THEN 0
ELSE -1
END AS [Flag Indicator]
FROM (
SELECT System_Name,
[Description],
[Monh],
[Year],
LAG(Value_used, 1,0) OVER (ORDER BY System_Name, [Description],[Year],[Monh]) AS PreviousQuota
FROM [CAPM_Reporting_Analytics].[dbo].[Capacity_Data_Reds]
) TB1
I am creating the YTD to use in my matrix on SSRS that is creating the pivot to show the evolution from month.
My problem is: Imagine that I want to create the report from Month 8. I want to add a indicator that shows
- If the last month (only consider the month 8 in this case) is above the previous month then Green
- If the previous month is null then Grey
- Else Red.
I want to get anything like this:
Where the trend is only valid between the value of the last and penultimate column (last and penultimate)
How can I do this?
Many thanks!!
I have a table [tblCalls] containing a date and a telephone number.[logdate] & [telephone]
I'm trying to produce an output similar to the following:
Date Mobiles Landlines
Nov 2016 28 47
Dec 2016 65 98
Jan 2017 11 17
... and so on
Using the following:
SELECT MONTH(logdate) as myDate,
SUM(CASE WHEN telephone LIKE '07%' THEN 1 ELSE 0 END) mobiles,
sum(CASE WHEN telephone NOT LIKE '07%' THEN 1 ELSE 0 END) landlines
FROM tblCalls
WHERE username='myusername' AND YEAR(logdate)='2016'
GROUP BY MONTH(logdate)
I can produce this:
myDate Mobiles Landlines
1 28 47
2 65 98
3 11 17
4 09 14
5 32 8
... and so on
My question is in 2 parts.
1. How do I combine the month and year together and span years (not just 2016).
2. I have another table [tblUsersLogs] which also contains a date [logdate] and a username, I'd like include a count from this table on the number of entries for a specific user grouped by months in the year to produce something like this...
Date Mobiles Landlines UsernameCount
Nov 2016 28 47 50
Dec 2016 65 98 44
Jan 2017 11 17 45
... and so on
Is this possible?
UPDATE (some sample data)
[tblCalls]
logDate telephone
2017-01-04 12:18:36.243 01507443000
2017-01-04 11:23:17.313 07880507000
2017-01-04 11:23:16.760 01216286000
2017-01-04 11:23:15.837 07541360000
2017-01-04 11:23:15.570 01970611000
[tblUserLogs]
logDate username
2017-01-04 12:23:51.530 usera
2017-01-04 12:23:38.350 usera
2017-01-04 12:23:08.530 userb
2017-01-04 12:22:45.020 userc
2017-01-04 12:22:35.437 usera
Hope that helps
Not clear on UserNameCount so I made an assumption and removed the WHERE
Select Date = Format(myDate,'MMM yyyy')
,mobiles = sum(CASE WHEN telephone LIKE '07%' THEN 1 ELSE 0 END)
,landlines = sum(CASE WHEN telephone NOT LIKE '07%' THEN 1 ELSE 0 END)
,UserNamesCount = count(Distinct Usernames)
From tblCalls
Where Year(logdate)=2016
Group By Format(myDate,'MMM yyyy')
Order By Month(myDate)
All you need to do is to change your dates all to the same day of the month and then leave the formatting to your presentation/reporting layer:
SELECT dateadd(m,datediff(m,0,logdate),0) as myDate -- This will return the first day of the month.
,SUM(CASE WHEN telephone LIKE '07%' THEN 1 ELSE 0 END) mobiles
,SUM(CASE WHEN telephone NOT LIKE '07%' THEN 1 ELSE 0 END) landlines
FROM tblCalls
WHERE username = 'myusername' -- Avoid using functions in your WHERE criteria.
AND logdate >= '20160101' -- Doing so makes your filtering much less efficient.
AND logdate < '20170101' -- For more info, google 'SARGability'.
GROUP BY dateadd(m,datediff(m,0,logdate),0)
If you absolutely have to format within your SQL query, you can use:
left(datename(month,logdate),3) + ' ' + cast(year(logdate) as nvarchar(4))
I try to get data year wise. I tried this query
select
year(SStartDate) as joinedyear ,
count(*) joined_total
from
Detail
where
client = 81
Group By
YEAR(StartDate)
union all
select
year(SEndDate) as leftyear,
count(*) left_total
from
Detail
where
client = 81
Group By
YEAR(SEndDate)
This shows correct data but this shows data like this
1900 12
2001 1
2012 3
2013 3
2016 45
1900 23
2002 34
2004 34
2015 1
2016 56
where as I want data like this
joinedyear joined_total leftyear left_total
1900 12 1900 45
2001 1 2002 34
2012 3 2004 34
2013 3 2015 1
2016 45 2016 56
Try This below query..it mat help you
select * from (
select year(SStartDate) as joinedyear ,
count(*) joined_total from Detail
where client=81
Group By YEAR(StartDate)
) as a
full outer join
(
select year(SEndDate) as leftyear , count(*) left_total from Detail
where client=81
Group By YEAR(SEndDate)
) as b
on a.joinedyear=b.leftyear
We have a table [Kpis] that looks like the following:
RawId EmpId Date Hour Min KpiValue KpiName
106 ABC123 20160310 8 0 3 Kpi1
124 ABC123 20160310 8 0 65 Kpi1
121 ABC123 20160310 8 15 12 Kpi2
109 ABC109 20160310 8 0 34 Kpi2
112 ABC908 20160310 9 5 3 Kpi1
118 ABC907 20160310 8 30 24 Kpi1
115 ABC123 20160310 8 15 54 Kpi1
I would like to group by EmpId, KpiName, Date, Hour. So, for example, with this data, Kpi1 for EmpId ABC123 at Hour 8 would be 122.
So I tried using the CASE statement, but the result is incorrect. I haven't checked the actual totals in the result, but the sums should be correct. It's the format of the result that's incorrect; every empid has two rows: one for Kpi1 and one for Kpi2.
select empid,
case kpiname when 'Kpi1' then sum(kpivalue) end as 'Kpi1',
case kpiname when 'Kpi2' then sum(kpivalue) end as 'Kpi2'
from
[Kpis]
where kpiname in ('Kpi1', 'Kpi2')
and date = 20160310 and hour = 8
group by empid, kpiname, hour
How can I use the Case statement to fix the results?
Thanks.
Put the case inside your sum, such that you for each KpiName only sums the relevant values.
SELECT
EmpId,
[Hour],
SUM(
CASE
WHEN KpiName = 'Kpi1' THEN KpiValue
ELSE 0
END
) Kpi1,
SUM(
CASE
WHEN KpiName = 'Kpi2' THEN KpiValue
ELSE 0
END
) Kpi2
FROM
Kpis
GROUP BY
EmpId,
[Hour]
This produces this output
EmpId Hour Kpi1 Kpi2
ABC109 8 0 34
ABC123 8 122 12
ABC907 8 24 0
ABC908 9 3 0
SUM fucntion have to be outside of CASE:
select empid,
sum(case kpiname when 'Kpi1' then kpivalue end) as 'Kpi1',
sum(case kpiname when 'Kpi2' then kpivalue end) as 'Kpi2'
from
[Kpis]
where kpiname in ('Kpi1', 'Kpi2')
and date = 20160310 and hour = 8
group by empid, kpiname, hour
You can also do this with the PIVOT functionality, which I believe is what you're actually trying to accomplish.
SELECT
*
FROM (
SELECT
EmpId,
KpiName,
[Hour],
KpiValue
FROM
Kpis
) SourceTable
PIVOT (
SUM(KpiValue)
FOR KpiName
IN ([Kpi1],[Kpi2])
) PivotTable
Which gives this output. Note the NULLs as opposed to the zeros, correctly showing the lack of data.
EmpId Hour Kpi1 Kpi2
ABC109 8 NULL 34
ABC123 8 122 12
ABC907 8 24 NULL
ABC908 9 3 NULL
This is the result of my first sql statement:
SELECT
count(*) countQuarter, Hour, Quarter,
ROW_NUMBER() OVER(ORDER BY Hour, Quarter ASC) AS rownum
FROM
(SELECT [ID] ,[simulationID] ,[time],
replace(str(time/3600,len(ltrim(time/3600))+abs(sign(time/359999)-1)) + ':' + str((time/60)%60,2) + ':' + str(time%60,2),' ','0') dtString,
(time/3600) Hour, (time/60)%60 Minute, case when (time/60)%60<15 then 15 when
(time/60)%60<30 then 30 when (time/60)%60<45 then 45 when (time/60)%60<60 then 60 end
Quarter ,[person] ,[link] ,[vehicle] FROM [TEST].[dbo].[evtLinks]
WHERE simulationID=#simulationID) B
GROUP BY Hour, Quarter
which gives the following results:
Count Hour Quarter Rownum
497 0 15 1
842 0 30 2
1033 0 45 3
1120 0 60 4
1235 1 15 5
1267 1 30 6
1267 1 45 7
1267 1 60 8
1267 2 15 9
1267 2 30 10
I desire a result, where the column fullCount is the sum of the Count of the actual row and the next 3!
Count Hour Quarter Rownum Fullcount
497 0 15 1 3492
842 0 30 2 4230
1033 0 45 3 4655
1120 0 60 4 ...
1235 1 15 5
1267 1 30 6
1267 1 45 7
1267 1 60 8
1267 2 15 9
1267 2 30 10
How can this be done with grouping or analytical functions in SQL Server?
For SQL Server 2012, yes this can be done:
declare #t table ([Count] int,[Hour] int,[Quarter] int,Rownum int)
insert into #t([Count],[Hour],[Quarter],Rownum) values
(497 , 0 , 15 , 1 ),
(842 , 0 , 30 , 2 ),
(1033 , 0 , 45 , 3 ),
(1120 , 0 , 60 , 4 ),
(1235 , 1 , 15 , 5 ),
(1267 , 1 , 30 , 6 ),
(1267 , 1 , 45 , 7 ),
(1267 , 1 , 60 , 8 ),
(1267 , 2 , 15 , 9 ),
(1267 , 2 , 30 , 10 )
select *,SUM([Count]) OVER (
ORDER BY rownum
ROWS BETWEEN CURRENT ROW AND
3 FOLLOWING)
from #t
Here I'm using #t as your current result set - you may be able to adapt this into your current query or may have to place your current query in a CTE.
Unfortunately, the ROWS BETWEEN syntax is only valid on 2012 and later.
Tested the logical scenario and it works, but I don't have your data, so in your case it should look roughly like this:
;WITH CTE as (SELECT count(*) countQuarter,Hour,Quarter,
ROW_NUMBER() OVER(ORDER BY Hour, Quarter ASC) AS rownum
FROM
(SELECT [ID] ,[simulationID] ,[time],
replace(str(time/3600,len(ltrim(time/3600))+abs(sign(time/359999)-1)) + ':' + str((time/60)%60,2) + ':' + str(time%60,2),' ','0') dtString,
(time/3600) Hour, (time/60)%60 Minute, case when (time/60)%60<15 then 15 when
(time/60)%60<30 then 30 when (time/60)%60<45 then 45 when (time/60)%60<60 then 60 end
Quarter ,[person] ,[link] ,[vehicle] FROM [TEST].[dbo].[evtLinks]
WHERE simulationID=#simulationID) B
GROUP BY Hour, Quarter)
SELECT *, CA.Fullcount
FROM CTE
CROSS APPLY (SELECT SUM(countQuarter) Fullcount FROM CTE C WHERE C.ID BETWEEN CTE.ID AND CTE.ID+3) CA