Related
I have a calendar table where working days are marked.
Now I need a running total called "current_working_day" which sums up the working days until the end of a month and restarts again.
This is my query:
select
WDAYS.Date,
WDAYS.DayName,
WDAYS.WorkingDay,
sum(WDAYS.WorkingDay) OVER(order by (Date), MONTH(Date), YEAR(Date)) as 'current_working_day',
sum(WDAYS.WorkingDay) OVER(PARTITION by YEAR(WDAYS.Date), MONTH(WDAYS.Date) ) total_working_days_per_month
from WDAYS
where YEAR(WDAYS.Date) = 2022
This is my current output
Date
DayName
WorkingDay
current_working_day
total_working_days_per_month
2022-01-27
Thursday
1
19
21
2022-01-28
Friday
1
20
21
2022-01-29
Saturday
0
20
21
2022-01-30
Sunday
0
20
21
2022-01-31
Monday
1
21
21
2022-02-01
Tuesday
1
22
20
2022-02-02
Wednesday
1
23
20
2022-02-03
Thursday
1
24
20
But the column "current_workind_day" should be like this
Date
DayName
WorkingDay
current_working_day
total_working_days_per_month
2022-01-27
Thursday
1
19
21
2022-01-28
Friday
1
20
21
2022-01-29
Saturday
0
20
21
2022-01-30
Sunday
0
20
21
2022-01-31
Monday
1
21
21
2022-02-01
Tuesday
1
1
20
2022-02-02
Wednesday
1
2
20
2022-02-03
Thursday
1
3
20
Thanks for any advice.
You can try to use PARTITION by with EOMONTH function which might get the same result but better performance, then you might only need to order by Date instead of using the function with the date.
select
WDAYS.Date,
WDAYS.DayName,
WDAYS.WorkingDay,
sum(WDAYS.WorkingDay) OVER(PARTITION by EOMONTH(WDAYS.Date) order by Date) as 'current_working_day',
sum(WDAYS.WorkingDay) OVER(PARTITION by EOMONTH(WDAYS.Date) ) total_working_days_per_month
from WDAYS
where YEAR(WDAYS.Date) = 2022
I have this table in DB2:
DATE
----------
09/11/2021
06/10/2021
28/11/2021
17/11/2021
11/10/2021
24/11/2021
07/11/2021
30/11/2021
I want to count how many times a date appeared in the table and group it by year and month, and display it like this:
| YEAR | OCTOBER | NOVEMBER |
----------------------------
| 2021 | 2 | 6 |
As months are a known quantity you could use a sum of a case statement:
select year(datecol) as year
,sum(case when month(datecol) = 1 then 1 else 0 end) as jan
,sum(case when month(datecol) = 2 then 1 else 0 end) as feb
,sum(case when month(datecol) = 3 then 1 else 0 end) as mar
,sum(case when month(datecol) = 4 then 1 else 0 end) as apr
,sum(case when month(datecol) = 5 then 1 else 0 end) as may
,sum(case when month(datecol) = 6 then 1 else 0 end) as jun
,sum(case when month(datecol) = 7 then 1 else 0 end) as jul
,sum(case when month(datecol) = 8 then 1 else 0 end) as aug
,sum(case when month(datecol) = 9 then 1 else 0 end) as sep
,sum(case when month(datecol) = 10 then 1 else 0 end) as oct
,sum(case when month(datecol) = 11 then 1 else 0 end) as nov
,sum(case when month(datecol) = 12 then 1 else 0 end) as dec
from datetest
group by year(datecol)
order by 1;
That will give you output similar to this:
YEAR JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC
----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
2018 0 0 0 0 0 0 0 0 0 0 3 0
2019 0 0 0 0 0 0 0 0 0 1 2 0
2020 0 0 0 0 0 0 0 0 0 1 1 0
2021 0 0 0 0 0 0 0 0 0 2 6 0
You may use a generic routine described at the link dynamic pivot SQL Query in Db2.
Use the following call to get the desired result set for your case:
CALL PIVOT
(
'SELECT YEAR (DATE) AS YEAR, TO_CHAR (DATE, ''MONTH'') AS MONTH FROM DATES'
, 'YEAR'
, 'MONTH'
, 'MONTH'
, 'count'
, 'SESSION.PIVOT'
, '-'
, ?, ?, ?
);
The result is:
YEAR
NOVEMBER
OCTOBER
2021
6
2
I'm trying to retrieve data based on Month of every year. It will get but sorting is not correct.
SELECT Client,DispacthDate,Models,Model1,Model2,Model3
FROM (
SELECT Client
,Concat(year(Audit_Date),' ',datename(month,Audit_Date)) as DispatchDate
,Models
,Count(Models) 'Units'
FROM dbo.ABC
GROUP BY Client,Concat(year(Audit_Date),' ',datename(month,Audit_Date)),Models
) abcd
PIVOT(SUM(Units) FOR Models IN (Model1,Model2,Model3)) as P
ORDER BY Client,DispatchDate
I'll get result set like this:
Client DispatchDate Model1 Model2 Model3
Client1 2017 December 0 0 0
Client1 2017 November 25 0 0
Client1 2018 January 21 0 0
Client1 2018 March 9 0 0
Client2 2017 December 8 0 0
Client2 2018 April 5 0 0
Client2 2018 August 0 0 0
Client2 2018 July 0 0 0
Client2 2018 March 0 0 0
Client3 2017 December 4 0 0
Client3 2017 November 687 0 0
Client3 2018 April 8 0 0
Client3 2018 January 0 0 0
But Required Data Like:
Client DispatchDate Model1 Model2 Model3
Client1 2018 January 21 0 0
Client1 2018 March 9 0 0
Client1 2017 November 25 0 0
Client1 2017 December 0 0 0
Client2 2018 March 0 0 0
Client2 2018 April 5 0 0
Client2 2018 July 0 0 0
Client2 2018 August 0 0 0
Client2 2017 December 8 0 0
Client3 2018 January 0 0 0
Client3 2018 April 8 0 0
Client3 2017 November 687 0 0
Client3 2017 December 4 0 0
Please Any one suggest me for my query.
From my understanding,
SELECT Client,DispacthDate,Models,Model1,Model2,Model3
FROM (
SELECT Client
,Concat(year(Audit_Date),' ',datename(month,Audit_Date)) as DispatchDate
,Models
,Count(Models) 'Units'
FROM dbo.ABC
GROUP BY Client,Concat(year(Audit_Date),' ',datename(month,Audit_Date)),Models
) abcd
PIVOT(SUM(Units) FOR Models IN (Model1,Model2,Model3)) as P
ORDER BY Client,
, DATEPART (YYYY, convert(date, DispacthDate)) desc -- here query has been changed.
, DATEPART (MM, convert(date, DispacthDate)) -- here query has been changed.
Don't convert the DispatchDate to string in the inner query. Keep it in date or datetime type. And then convert it at the outer query
SELECT Client,
DATENAME(YEAR, Audit_Date) + ' ' + DATENAME(MONTH, Audit_Date) AS DispatchDate,
Models, Model1, Model2, Model3
FROM (
SELECT Client
,DATEADD(MONTH, DATEDIFF(MONTH, 0, Audit_Date), 0) as Audit_Date
,Models
,Count(Models) AS Units
FROM dbo.ABC
GROUP BY Client,
DATEADD(MONTH, DATEDIFF(MONTH, 0, Audit_Date), 0), month(Audit_Date)),
Models
) abcd
PIVOT(SUM(Units) FOR Models IN (Model1,Model2,Model3)) as P
ORDER BY Client, Audit_Date
I have a SQL query where I am getting the row number for a count of employees per division and per month at the beginning of the month and the end of the month. To do that, I use a payroll end date which is a weekly date. So in essence I have 4 dates where employee counts are shown. Some months have 5 dates which makes the row count for that month 5 instead of 4.
I then need to build an SSRS report to show only the first employee count and the last employee count per division, per month. I have the first number since I am using =IIF(Fields!RowNumber.Value = 1, Fields!EMPCOUNT.Value, 0)
The problem I have now is getting the last employee count where I need to conditionally select a count where row number needs to be 5 if exists or 4 if it doesn't exist. I'm not sure how to get the expression to work in SSRS. Sample data is below.
PRCo EMPCOUNT udDivision PREndDate ROWNUM Type
1 89 Civil 2018-01-06 00:00:00 1 1
1 97 Civil 2018-01-13 00:00:00 2 1
1 97 Civil 2018-01-20 00:00:00 3 1
1 97 Civil 2018-01-27 00:00:00 4 1
1 16 Colorado 2018-01-06 00:00:00 1 1
1 18 Colorado 2018-01-13 00:00:00 2 1
1 14 Colorado 2018-01-20 00:00:00 3 1
1 10 Colorado 2018-01-27 00:00:00 4 1
1 94 Civil 2018-02-03 00:00:00 1 2
1 91 Civil 2018-02-10 00:00:00 2 2
1 92 Civil 2018-02-17 00:00:00 3 2
1 91 Civil 2018-02-24 00:00:00 4 2
1 16 Colorado 2018-02-03 00:00:00 1 2
1 16 Colorado 2018-02-10 00:00:00 2 2
1 18 Colorado 2018-02-17 00:00:00 3 2
1 19 Colorado 2018-02-24 00:00:00 4 2
1 92 Civil 2018-03-03 00:00:00 1 3
1 91 Civil 2018-03-10 00:00:00 2 3
1 88 Civil 2018-03-17 00:00:00 3 3
1 92 Civil 2018-03-24 00:00:00 4 3
1 90 Civil 2018-03-31 00:00:00 5 3
1 19 Colorado 2018-03-03 00:00:00 1 3
1 26 Colorado 2018-03-10 00:00:00 2 3
1 25 Colorado 2018-03-17 00:00:00 3 3
1 27 Colorado 2018-03-24 00:00:00 4 3
1 24 Colorado 2018-03-31 00:00:00 5 3
I would do this in your query rather than trying to get it to work directly in SSRS. There might be a simpler way than this but this is just based on your existing query.
Please note this is untested and just off the top of my head so it may need some editing before it will work.
SELECT * INTO #t FROM YOUR_EXISTING_QUERY
SELECT DISTINCT
PRCo
, udDivision
, YEAR(PREndDate) AS Yr
, MONTH(PREndDate) AS Mnth
, FIRST_VALUE(EMPCOUNT) OVER(PARTITION BY PRCo, udDivision, YEAR(PREndDate), MONTH(PREndDate) ORDER BY ROWNUM) AS OpeningEMPCOUNT
, LAST_VALUE(EMPCOUNT) OVER(PARTITION BY PRCo, udDivision, YEAR(PREndDate), MONTH(PREndDate) ORDER BY ROWNUM) AS CLosing_EMPCOUNT
FROM #t
Yo might need to include Type not sure what this does but you get the idea hopefully.
The FIRST_VALUE and LAST_VALUE functions simply get the first/last value within the partition defined, in your case PRCo, udDivision and then just the year and month portion of the payroll end date, the first and last positions are determined by the order clause, in this case row number.
friends:
I'm now have a problem about conditional calculation in SQL Server.
I have set some data from SQL Server as an example in excel like this:
No Employee Month Commission1 Commission2
1 A Jan 10 5
2 A Jan 10 4
3 B Jan 15 3
4 B Jan 15 4
5 C Jan 10 3
6 C Jan 10 4
7 D Jan 13 3
8 D Jan 13 4
9 DM Jan 0 6
10 DM Jan 0 8
11 A Feb 15 4
12 A Feb 15 5
13 B Feb 20 5
14 B Feb 20 4
15 C Feb 9 3
16 C Feb 9 4
17 D Feb 14 5
18 D Feb 14 6
19 DM Feb 0 13
20 DM Feb 0 10
And the result I want is like this:
Employee Jan No# Feb No#
A 20 2 30 2
B 30 2 40 2
C 20 2 18 2
D 26 2 28 2
DM 44 10 59 10
For every sales,Employee A,B,C,D only have commission1 as payment,the commission2 is for DM. So , in Jan , DM's commission is SUM(E2:E9)
I can do it easy in excel , but how can I do this in sql server?
I make my try code like this:
select [Month],Employee,SUM(Commission1) Commission,count(distinct([No])) No#
from table1
WHERE Employee IN ('A','B','C','D')
group by [Month],Employee
union
select 'DM' as Employee,[Month],SUM(Commission2) Commission,count(distinct([No])) No#
from table1
WHERE Employee IN ('A','B','C','D','DM')
group by [Month],Employee
And I get the result
Employee Month Commission No#
A Jan 20 2
B Jan 30 2
C Jan 20 2
D Jan 26 2
DM Jan 44 10
A Feb 30 2
B Feb 40 2
C Feb 18 2
D Feb 28 2
DM Feb 59 10
The result format is not what I want.I tried pivot after this query,but failed,it seems I only can pivot one state?
Another question: If I want the month growth automatic (In actual data , there's not only Jan and Feb) in the result ,not write [Jan],[Feb],[Mar]... in pivot code, how to do it?
Who can help me?
Thanks!
Here is a PIVOT solution:
Test data:
DECLARE #t table(Employee varchar(2), Month char(3), Commission1 int, Commission2 int)
INSERT #t values
('A','Jan',10,5 ),('A','Jan',10,4),('B','Jan',15,3),
('B','Jan',15,4 ),('C','Jan',10,3),('C','Jan',10,4),
('D','Jan',13,3 ),('D','Jan',13,4),('DM','Jan',0,6),
('DM','Jan',0,8 ),('A','Feb',15,4),('A','Feb',15,5),
('B','Feb',20,5 ),('B','Feb',20,4),('C','Feb',9,3),
('C','Feb',9,4 ),('D','Feb',14,5),('D','Feb',14,6),
('DM','Feb',0,13),('DM','Feb',0,10)
Query:
;WITH CTE as
(
SELECT
Employee, Month,
CASE WHEN Employee = 'DM' THEN
SUM(Commission2) over (partition by [Month])
ELSE Commission1 END com,
CASE WHEN Employee = 'DM'
THEN row_number() over
(PARTITION BY Employee, [Month] ORDER BY (SELECT 1)) ELSE 1 END rn
FROM #t
)
SELECT Employee, [Jan], [Feb], [Mar] -- add more months
FROM
CTE
PIVOT
(SUM(com)
FOR [Month] IN ([Jan], [Feb], [Mar])) AS pvt -- add more months
WHERE rn = 1
Result:
Employee Jan Feb Mar
A 20 30 NULL
B 30 40 NULL
C 20 18 NULL
D 26 28 NULL
DM 44 59 NULL
In SqlServer you can do so using PIVOT operator as like below:
Please refer PIVOT syntax
select tmp.employee,pv.[jan] as Jan_Commission, pv.[feb] as Feb_Commission from
(
select employee,month,commission1 from table_name
)tmp
pivot (
sum(commission1)
for [month] in ([jan],[feb])
)pv;