Get total sum for each month in DAX - sql-server

I have a tabular mode analysis server connected to a sql server database. I want to get the total x per month, and I have the total x per day. So for example, I have a table DailyEvent with the first 2 columns like this, and I want the column "MonthXCount":
TimeID XCount MonthXCount
20160429 3 11
20160430 8 11
20160501 4 4
So the total XCount for April is 11, so for every day in April I want 11. The total X count for may is 4 (so far).
What I have now is a MonthToDate total I think, calculated as:
=TOTALMTD(SUM('DailyEvent'[XCount]),'DailyEvent'[TimeID])
But I want to then have a column that puts the last value of the month in for every day of the month.
The end goal is to have a XCount by month graph in PowerBI, so I might not need to add the column here... I might be able to just tell PowerBi to graph the last day of the month, but I'm not sure how to do that and thought this would be easier.

SqlConnection sqlConnection1 = new SqlConnection("Your Connection String");
SqlCommand cmd = new SqlCommand();
SqlDataReader reader;
cmd.CommandText = "begin transaction t
update table dailyevent
set monthxcount = (select top(1) monthxcount
from dailyevent
where MONTH(timeID) = 4
order by monthxcount desc)
where MONTH(timeID) = 4
--commit only if the rows affected corresponds to the number of rows found for the month of april.
commit";
cmd.CommandType = CommandType.Text;
cmd.Connection = sqlConnection1;
sqlConnection1.Open();
reader = cmd.ExecuteReader();
// Data is accessible through the DataReader object here.
sqlConnection1.Close();

Do you have a Calendar Table in your model connected to your data table?
If yes, let's say the Calendar Table is called DimDate and that it contains a column called YearMonth, then the formula would be:
Month Sales := SUMX(
VALUES(DimDate[YearMonth]),
SUM(DailyEvent[XCount])
)
If you don't have a Calendar Table, then you can create a calculated column in your table called YearMonth with this formula:
=LEFT(DailyEvent[TimeID], 6)
Then calculate the sum of Month Sales with:
Month Sales := SUMX(
VALUES(DailyEvent[YearMonth]),
SUM(DailyEvent[XCount])
)
Hope this helps!
A note with respect to the formula you were using:
Time intelligence functions, such as TOTALMTD, require Calendar Tables. Therefore, be sure to add one to your data model before using them.
Edit:
Another solution could be to create a date column:
= DATE(
LEFT(DailyEvent[TimeID], 4),
MID(DailyEvent[TimeID], 5, 2),
1)
Then drop that column in the X-axis of the graph and the XCount column in the Y-axis.

You could use a measure calculation in Power BI, or in SSAS model, if there is a calendar table, make sure it is marked as date table otherwise the time logic will not work. I used the following query (DAX) it calculates the Month To Date
MtD :=CALCULATE(SUM('DailyEvent'[XCount]),DATESMTD('DateTabe'[calendarDate]))
If however there is no calendar or you are working with the be-spoke calendar, this may help
Running Totals Whitout a Traditional Calendar Table

Related

Creating Attendance Report with SSRS

I am trying to create a Attendance result set in SQL Server for using it in a SSRS report. The Employee Attendance table is as below:
EmpId
ADate
In
Out
1
2023-01-01
8:00
15:00
I need to calculate the Total working days for all months in a year and display the number of working days per employee. Report format should be as follows:
Saturday and Sunday being weekend, I can able to get the no of working days monthly.
Another table tbl_Holiday has entries for holidays Fromdate and ToDate. I need to consider that also when calculating working days. Several number of results i got from the internet for calculating this. But when creating a view using this data , it has to calculate workdays for each employee row
SELECT
EmpName, EmpId,
(SELECT COUNT(*) FROM tbl_EmpAttendance
WHERE EmpRecId = A.RecId
GROUP BY MONTH(Adate), YEAR(Adate)) AS WorkedDays,
dbo.fn_GetWorkDays(DATEFROMPARTS(YEAR(ADate), MONTH(ADate), 1), EOMONTH(ADate)) AS workingDays
FROM
tbl_Employee A
LEFT JOIN
tbl_EmpAttendance B ON A.RecId = B.EmpRecId
fn_GetWorkDays - calculates the working days for month.
I need to get number of holidays from tbl_holiday too, I understand that this query is becoming more complex than I thought. There must be simpler way to achieve this, can anyone please help?
I tried to get the result in one single view, for using that as SSRS report dataset

Count by days, with all days

I need to count records by days, even if in the day were no records.
Count by days, sure, easy.
But how i can make it to print information, that 'in day 2018-01-10 was 0 records)
Should I use connect by level? Please, any help would be good. Can't use plsql, just oracle sql
First you generate every date that you want in an inline view. I chose every date for the current year because you didn't specify. Then you left outer join on date using whichever date field you have in that table. If you count on a non-null field from the source table then it will count 0 rows on days where there is no join.
select Dates.r, count(tablename.id)
from (select trunc(sysdate,'YYYY') + level - 1 R
from dual
connect by level <= trunc(add_months(sysdate,12),'YYYY') - trunc(sysdate,'YYYY')) Dates
left join tablename
on trunc(tablename.datefield) = Dates.r
group by Dates.r

SQL Server: Get the last row entries (more than one) with sql query

Scenario: a user will copy and paste data (multiple rows) from an Excel sheet onto my webpage and press submit. When this occurs, the data will be saved into a SQL Server table. The current date will also be saved next to each row.
Now, in another gridview, I would like to view only these multiple rows that have been pasted /saved to DB that certain day.
So I was thinking about using TOP / MAX(date) but Top returns specified rows only, and MAX only 1 row.
Anyone out there that has done this before or can help get a working query?
Use TOP WITH TIES in order to get all last entries:
SELECT TOP(1) WITH TIES
...
ORDER BY submit_date DESC;
Is "that certain day" based on a specific day or a 24 hour interval?
You can make the gridview query the data where the date field is higher than or equal to dateadd(dd, -1, getdate())
Or if you mean the current day as in the current date, where the date is equal to the date of getdate.

How to calculate if date in database has expired within LINQ

I have a requirement to find all records using EntityFramework via LINQ where the date stored in the database is almost expired. If the date in the database is almost 2 years old then it is expired (2 years - 90 days). We want users to be notified at 90 days prior to 2 years.
My users table has DateStamp column with the date. Thus the entity has a DateStamp property. I'm not sure how to construct the LINQ to determine if the date is 2 years - 90 days or not.
from u in Users
where u.DateStamp.....what's next?
You can use temp DateTime variable
DateTime temp = DateTime.Now.AddYears(-2).AddDays(90);
var users = (from u in Users where u.DateStamp <= temp select u);

SQL Server Retrieving Recurring Appointments By Date

I'm working on a system to store appointments and recurring appointments. My schema looks like this
Appointment
-----------
ID
Start
End
Title
RecurringType
RecurringEnd
RecurringTypes
---------------
Id
Name
I've keeped the Recurring Types simple and only support
Week Days,
Weekly,
4 Weekly,
52 Weekly
If RecurringType is null then that appointment does not recur, RecurringEnd is also nullable and if its null but RecurringType is a value then it will recur indefinatly. I'm trying to write a stored procedure to return all appointments and their dates for a given date range.
I've got the stored procedure working for non recurring meetings but am struggling to work out the best way to return the recurrences this is what I have so far
ALTER PROCEDURE GetAppointments
(
#StartDate DATETIME,
#EndDate DATETIME
)
AS
SELECT
appointment.id,
appointment.title,
appointment.recurringType,
appointment.recurringEnd,
appointment.start,
appointment.[end]
FROM
mrm_booking
WHERE
(
Start >= #StartDate AND
[End] <= #EndDate
)
I now need to add in the where clauses to also pick up the recurrences and alter what is returned in the select to return the Start and End Dates for normal meetings and the calculated start/end dates for the recurrences.
Any pointers on the best way to handle this would be great. I'm using SQL Server 2005
you need to store the recurring dates as each individual row in the schedule. that is, you need to expand the recurring dates on the initial save. Without doing this it is impossible to (or extremely difficult) to expand them on the fly when you need to see them, check for conflicts, etc. this will make all appointments work the same, since they will all actually have a row in the table to load, etc. I would suggest that when a user specifies their recurring date, you make them pick an actual number of recurring occurrences. When you go to save that recurring appointment, expand them all out as individual rows in the table. You could use a FK to a parent appointment row and link them like a linked list:
Appointment
-----------
ID
Start
End
Title
RecurringParentID FK to ID
sample data:
ID .... RecurringParentID
1 .... null
2 .... 1
3 .... 2
4 .... 3
5 .... 4
if in the middle of the recurring appointments schedule run, say ID=3, they decide to cancel them, you can follow the chain and delete the remaining ID=3,4,5.
as for expanding the dates, you could use a CTE, numbers table, while loop, etc. if you need help doing that, just ask. the key is to save them as regular rows in the table so you don't need to expand them on the fly every time you need to display or evaluate them.
I ended up doing this by creating a temp table of everyday between the start and end date along with their respective day of the week. I limited the recurrence intervals to weekdays and a set amount of weeks and added where clauses like this
--Check Week Days Reoccurrence
(
mrm_booking.repeat_type_id = 1 AND
#ValidWeeklyDayOfWeeks.dow IN (1,2,3,4,5)
) OR
--Check Weekly Reoccurrence
(
mrm_booking.repeat_type_id = 2 AND
DATEPART(WEEKDAY, mrm_booking.start_date) = #ValidWeeklyDayOfWeeks.dow
) OR
--Check 4 Weekly Reoccurences
(
mrm_booking.repeat_type_id = 3 AND
DATEDIFF(d,#ValidWeeklyDayOfWeeks.[Date],mrm_booking.start_date) % (7*4) = 0
) OR
--Check 52 Weekly Reoccurences
(
mrm_booking.repeat_type_id = 4 AND
DATEDIFF(d,#ValidWeeklyDayOfWeeks.[Date],mrm_booking.start_date) % (7*52) = 0
)
In case your interested I built up a table of the days between the start and end date using this
INSERT INTO #ValidWeeklyDayOfWeeks
--Get Valid Reoccurence Dates For Week Day Reoccurences
SELECT
DATEADD(d, offset - 1, #StartDate) AS [Date],
DATEPART(WEEKDAY,DATEADD(d, offset - 1, #StartDate)) AS Dow
FROM
(
SELECT ROW_NUMBER() OVER(ORDER BY s1.id) AS offset
FROM syscolumns s1, syscolumns s2
) a WHERE offset <= DATEDIFF(d, #StartDate, DATEADD(d,1,#EndDate))
Its not very elegant and probably very specific to my needs but it does the job I needed it to do.

Resources