I have a large data set (called input below) which contains a variety of information such as sales dates, transaction dates, payments, sales.
The user can produce a report by year, quarter or month to show the amount of payment in a particular month/quarter/year of a certain sales year. So you could have a payment 5 years after the initial sale, i.e. a payment in 2016 relating to the sales year of 2011.
The user can decide whether they want to have these payment periods by month/quarter/year at the beginning of the code through the use of macro variables (i.e. %let ReportBasis = Year) and ReportBasis can be called on through the rest of the code without manual adjustments.
The report is produced using:
proc sql;
create table report as
select sales_year, &ReportBasis, Sum(Sales) as Sales
from input
group by sales_year, &ReportBasis;
quit;
Now the issue I am having is that if there is no payment in a particular period for all sales years in question, then there is no row for that period. This produces a layout problem.
I require a solution to this which can be dynamic due to the nature of the macro variable (changing from year to month to quarter).
So I have this (example):
2011 Month 11 100
2011 Month 12 250
2011 Month 13 85
2011 Month 15 90
2011 Month 16 300
But I require this:
2011 Month 11 100
2011 Month 12 250
2011 Month 13 85
2011 Month 14 0
2011 Month 15 90
2011 Month 16 300
where there is no actual payment in month 14 in all of my data (even other years 2012, 2013 etc.), so it doesn't show up in my first table, but the second table still cleverly knows to include it.
Thanks in advance.
Here is one solution that assumes that all years and reports are represented in input, although not all combinations:
create table report as
select sy.sales_year, r.rb, Sum(i.Sales) as Sales
from (select distinct sales_year from input) sy cross join
(select distinct &ReportBasis as rb from input) r left join
input i
on i.sales_year = sy.sales_year and i.&ReportBasis = r.&ReportBasis
group by sy.sales_year, r.rb;
Related
At my last meeting someone asked me if it was possible to hide people who where ill since a year from a dashboard. So I'm searching for the best way to actually KNOW who has been ill for 12 months.
I am working with a table with the number of days you've been absent for every kind of absence you could have, the number of days you should have been working that month, with a row per person, department and profession each month.
So it looks something like this :
PersonID
YEAR
MONTH
DEPARTMENT
PROFESSION
Absence1
Absence2
Absence3
WORKING DAYS OF THE MONTH...
11111
2021
07
HR
ASSISTANT
0
2
0
22
11111
2021
08
HR
ASSISTANT
0
0
0
22
==> So if I'm on a row of July 2021 I need to check the lines from June 2020 to June 2021.
My guess is that I need to add a column to this table who will say (with some kind of loop maybe) "if for the last 12 months (rows) the total number of days of absence equal the number of working days of the last 12 months then "ILL FOR A YEAR OR MORE" for each person (knowing that a person can work in more than one department or more than one profession so she'll have more than one row per month).
But I really have no idea how to actually write it in a script as I usually do very basic things. I'm using SQL SERVER and have 429 207 rows in the table. I'm thinking about doing it in the whole table and not only treating this month's rows because in the dashboard we show an historic.
Your table is heavily denormalized. If you want to represent all this information in the database, I would have expected the following tables, instead of just one:
Person
Department
Illness (list of illnesses)
IllnessAbsence (join table between Person and Illness)
Either way, you can get the information you need with something like this:
I've assumed you want the whole table, so you need a window function
We need to flip the logic on its head: exclude all rows which have no non-absence in the last 12 months
SELECT
PersonID,
YEAR,
MONTH,
DEPARTMENT,
PROFESSION,
ILLNESS1,
ILLNESS2,
ILLNESS3,
[WORKING DAYS OF THE MONTH]
FROM (
SELECT *,
NotIllLast12Months = COUNT(CASE WHEN DATEFROMPARTS(YEAR + 1, MONTH, 1) >= GETDATE()
AND ILLNESS1 + ILLNESS2 + ILLNESS3 = 0 THEN 1 END)
OVER (PARTITION BY ID)
FROM HETP_ABS
) abs
WHERE NotIllLast12Months > 0;
I have been given population data like this;
Year Region Population
----------------------------------
2012 District1 1000
2012 District2 1500
2012 District3 2000
Now I have to make a cube where a user can filter population in Month, Quarter and Year level. So I decided to enter data into a fact table with each and every month of the given year that means 12 records for each District with the same given number. So if a user asks for any month he will get the same count. But now the problem is if user does not filter it by Month, Quarter and Year I get the Sum of all the data that means District1 will display 12 times 1000 = 12000. How can I get 1000 for district1 at any given time? If data is in multiple years then also it should not sum them up. Is my approach wrong? Hope I am clear enough to explain the problem.
Your fact is a semi additive measure, more info at http://msdn.microsoft.com/en-us/library/ms175356.aspx
I would like to get a running tally of how many widgets were/are rented at any one time, by month, by year. Data is held in an MS Access 2003 db;
Table name: rent_table
Fields:
rentid
startdate
enddate
rentfee
rentcost
bookingfee
Something like; Count number of rentid's that fall between month/year, then group them?
e.g. if a widget was rented from 5th Jan 2014 to 8th April 2014 it would appear as a count in Jan, Feb, Mar and April tally's.
Many thanks.
EDIT
More details (sorry);
Access db is fronted by classic ASP.
If possible I don't want to create any new tables.
No input is required in order to run the report.
There are around 350-400 widgets that could be rented at any one time.
Each widget is rented exclusively.
Report output example;
Month | Year | NumRented
Jan 2014 86
Feb 2014 113
...
Can a query pick up dates within dates? So literally do a count of the table where date >Dec 31st 2013 AND <1st Feb 2014 (to grab a count for all of January 2014) and would that include the example of the rent starting on the 5th Jan? So I could just do twelve counts for each year?
create a calendar table, e.g.
table = cal_yyyymm with one column dt_yyyymm as numeric field
populate the table with ... say 5 or 10 years of data
201401 201402 201403 ... 60 or 120 rows, a small table
make a sql
Select
dt_yyyymm,
count(*) as cnt
From cal_yyyymm
Left Join rent_table
On format(startdate,"yyyymm") >= dt_yyyymm
And dt_yyyymm >= format(enddate,"yyyymm")
think about the complications in the data -- --
widget was rented from 5th Jan 2014 to 8th Jan 2014
and again rented from 11th Jan 2014 to 21st Jan 2014
does this count at 1 or 2 in the month?
if it is 1, then the sql gets more complicated because
the rent_table first needs to have its dates converted
to yyyymm format, and second needs to be de-duped on rentid,
and third then joined to cal_ On the dates...
I am making a payroll system using vb6 with ms access as database. I have 3 tables in ms access namely:
tblemployee, tblattendance, tblpayroll
I want to get the payroll of all employees for the month of ex april, year 2013. All these datas will be from tblattendance.
Ex. (Some fields are hidden)
tblattendance:
Empid Day Month Year totalhourworkfor1day
1 1 april 2013 8
2 1 april 2013 5
1 2 april 2013 8
2 2 april 2013 5
tblpayroll:
empid month year Totalhoursworkfor1month
1 april 2013 16
2 april 2013 10
After querying for the month of april year 2013, all the totalhourworkfor1day for 1 employee will be added and the result will save in to Totalhoursworkfor1month.
How to do this? Considering that from my vb6, I only need to select the month and year to generate the payroll and after it will display to the listview
Tried code:
insert into tblpayroll(empid,month,year,hourswork)
select id,month, year, sum(hourswork) from tblattendance where empid=id group by empid;
Does this help?
The dates are just one field. I have used the MinOfWorkDay so as to avoid complications with months ending on 28,29,30,31. But this can be worked around if you want to have "month ending". In any event you could format results to simply show the month/year.
It could further enhanced by the HAVING clause defaulting to the month just ended, or using "from" and "to" dates entered on a form.
INSERT INTO tblPayroll ( Empid, HoursWorked, MonthEnd )
SELECT tblWork.Empid, Sum(tblWork.WorkHours) AS SumOfWorkHours, Min(tblWork.Workday) AS MinOfWorkday
FROM tblWork
GROUP BY tblWork.Empid
HAVING (((Min(tblWork.Workday)) Between #4/1/2013# And #4/30/2013#));
I'd be pleased to give more help if you come back with more questions.
15 Apr: I boobed! I assumed you would be processing your data in MS Access. I don't know vb6 so can't help any more. Could your whole project be done in access?
I am novice with SSRS.
I have a report which should display 60 months (5 years displayed like Jan 1999, feb 1999 & so on till the end of 60 months) and its corresponding sales amount. I want to get averages for the first 12 months (i.e for the 1st year) and so on. Is it possible? My dataset just gives me all the 60 months row-by-row.I am using matrix for my report.
Thanks,
User007.
I would add some nested row grouping to the matrix. The higher-level group would be by year, which would allow you to have a row in the matrix that totals/averages all of the data for the year. The inner group would be by month, giving you the individual month rows as your dataset returns them.
Here is some information about defining and using groups