I need to build a report that has custom quarter periods as shown below:
Quarter 1 - Jul, Aug, Sep
Quarter 2 - Oct, Nov, Dec
Quarter 3 - Jan, Feb, Mar
Quarter 4 - Apr, May, June
I'm a bit lost on how to approach this as I need to create a parameter where if they select quarter 1 it should only display data for the corresponding months.
Is there anyone that can suggest something?
Script looks as follows:
SELECT
ATD.TrnYear,
ATD.TrnMonth,
ATD.Invoice,
ATD.InvoiceDate,
ATD.Salesperson,
ATD.Customer,
ATD.StockCode,
ATD.ProductClass,
ATD.QtyInvoiced,
ATD.NetSalesValue,
ATD.CostValue,
AC.Name
FROM
ArTrnDetail ATD
JOIN ArCustomer AC ON ATD.Customer = AC.Customer
So I would need to add how to distinguish when the user selects the quarter.
Much appreciated.
Assuming your ATD.TrnMonth column use integer to represent months, I added an additional column to your query to indicate quarters (QTR). Also added the condition which will filter your result based on the user selection (WHERE Qtr = #quarter). This will be your dataset query.
SELECT *
FROM
(SELECT
CASE
WHEN ATD.TrnMonth IN (7,8,9) THEN 1
WHEN ATD.TrnMonth IN (10,11,12) THEN 2
WHEN ATD.TrnMonth IN (1,2,3) THEN 3
WHEN ATD.TrnMonth IN (4,5,6) THEN 4
END as Qtr,
ATD.TrnYear,
ATD.TrnMonth,
ATD.Invoice,
ATD.InvoiceDate,
ATD.Salesperson,
ATD.Customer,
ATD.StockCode,
ATD.ProductClass,
ATD.QtyInvoiced,
ATD.NetSalesValue,
ATD.CostValue,
AC.Name
FROM ArTrnDetail ATD JOIN ArCustomer AC ON ATD.Customer = AC.Customer
) as ArTrnDetail
WHERE Qtr = #quarter
In your report builder, create paramater with these settings:
GENERAL TAB
Name: quarter
Prompt: (whatever you want displayed for user)
AVAILABLE VALUES TAB
select Specify Values, and add 4 available values.
The label should be 1, 2, 3, and 4 (quarters) and the value should be the labels you want displayed in your dropdown list. Make sure the labels correspond with your values (quarters)
DEFAULT VALUES TAB
For example, when the report runs and you want the report to default to the first quarter. Select Specify Values, put 1 in the value. Leave this tab if you don't want defaults.
Note - This is the configuration for a single value dropdown. If you want the user to be able to select multiple values. In the "General" tab of the parameter, check "Allow multiple values" and change your query condition from WHERE Qtr = #quarter to WHERE Qtr IN (#quarter).
You need to map your data to a Date Dimension.
When you have done that you would have a fact table that can be joined to your date table. Either by an surrogatekey or a businesskey.
An example could be.
Query for Report
Select SalesAmount,SalesDate,Employee from fact.Sales S
inner join Dim.Datedimension d on s.SalesDate = d.Date
where d.QuarterNo = #DateParameter
Query for filter
Select distinct QuarterNo,QuarterLabel(Your Quarter 1 - Jul, Aug, Sep) From Dim.Datedimension
QuarterNo will be your value in parameter settings.
QuarterLabel will be your label.
Remember to adjust your date dimension to match your special quarters.
Related
I have a tricky situation in Microsoft SQL Server 2016, in which I need to get a list of dates that an employee was in Leave of Absence (LOA) in a PayPeriod, with fixed PeriodStart and fixed PeriodEnd columns.
See the figure below (the source dataset):
I have 4 employees in 5 rows of a dataset.
PeriodStart and PeriodEnd are fixed always, with the values Dec 15 and Dec 22 respectively (for 2020). I have each employee's LOA Start Date and LOA End Date in separate columns. The source dataset will have only one set of PeriodStart and PeriodEnd dates at any given time. Say, in the above case, it is ALWAYS Dec 15 and Dec 22. In someother cases, it will be Dec 22 and Dec 29. But only one range at a given time. The source dataset cannot contain Dec 15 - Dec 22 for Employee X, and Dec 22 - Dec 29 for Employee Y.
The desired output is as below:
The challenge here is, I am using our client's Query Builder, which cannot use T-SQL objects such as Temp tables (#), Table Variables (#), Common Table Expressions (CTE), User Defined Functions or even Views.
This is purely ad-hoc reporting, where you can ONLY create derived tables (or subqueries) and have an alias name and use it as a dataset. Such a dataset can be used in JOINs, and other regular stuff.
For example:
SELECT a, b
FROM
(SELECT t1.a, t2.b
FROM table1 t1
INNER JOIN table2 t2
ON t1.ID = t2.ID) XYZ
The derived table (or sub query) XYZ is the main dataset for me.
I need my desired output to be aliased XYZ.
Can anyone help me achieve this?
SELECT
yourTable.EmployeeID,
DATEADD(DAY, calendar.date_id, yourTable.PeriodStart)
FROM
(
SELECT
ROW_NUMBER() OVER (ORDER BY the_primary_key) - 1 AS date_id
FROM
any_big_enough_table
)
AS calendar
INNER JOIN
yourTable
ON calendar.date_id <= DATEDIFF(DAY, yourTable.PeriodStart, yourTable.PeriodEnd)
AND calendar.date_id >= DATEDIFF(DAY, yourTable.PeriodStart, yourTable.LOAStartDate)
AND calendar.date_id <= DATEDIFF(DAY, yourTable.PeriodStart, yourTable.LOAEndDate)
Please excuse typos, I'm on my phone.
I'm building a report in SQL Server Report Builder.
I want to have:
Drop-down parameter of month and year (i.e. "May 2018").
Second drop-down parameter would determine if the report is month-to-date or year-to-date.
I would like the first drop-down parameter to automatically update itself as time progresses. For example, on July 1, 2018, a "June 2018" option would be added automatically.
Is there a way to do this?
Create a new dataset for this drop down in your SSRS report and use the following query for your dataset:
SELECT FORMAT( EOMONTH(DATEADD(MONTH , -n , CAST(GETDATE() AS DATE)))
, 'MMM yyyy') [MMM_YYYY]
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS n
FROM
(VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) x1(x),
(VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) x2(x)
) x
WHERE n <= 24 --<-- change here to get upto last hundred months
ORDER BY n
It will give you for last 24 months in your drop down list, change the where clause to get more months shown in your drop down list.
select
Users.UserId
,Users.FirstName + ' ' + Users.LastName AS
,[Month]
,[Day]
,x.[Przych]
,x.[Wych]
,x.[Przych] + [Wych] as [Ogół]
from
(select
CaseActionHistory.UserId
,month(CaseActionHistory.DateAdded) AS [Month]
,day(CaseActionHistory.DateAdded) AS [Day]
,sum(case when CaseActionHistory.CaseActionDefinitionId in (14,15,16) then 1 else 0 end) AS [Przych]
,sum(case when CaseActionHistory.CaseActionDefinitionId in (20,21,22,23,26) then 1 else 0 end) AS [Wych]
from CaseActionHistory
where CaseActionHistory.CaseActionDefinitionId in (14,15,16,20,21,22,23,26)
group by month(CaseActionHistory.DateAdded),day(CaseActionHistory.DateAdded), CaseActionHistory.UserId
order by month(CaseActionHistory.DateAdded) DESC,day(CaseActionHistory.DateAdded) DESC
OFFSET 0 rows
) AS x
inner join Users on x.UserId = Users.UserId
I'm trying to run out something out of this. My problem is: the results of such query are displayed like this:
User Month Day X
User1 7 31 6
User2 7 31 7
User3 7 31 9
User1 7 30 8
User2 7 30 7
User3 7 30 8
User4 7 31 10
User5 7 31 20
User6 7 31 23
User4 7 30 5
User5 7 30 7
User6 7 30 65
So in fact few Users are grouped into small groups which are displayed first, then 2nd group, etc. so I suppose there's a problem either with group by or order by.
As an addition I'd like to ask a question concerning parameters in SQL Server. Out of code below I'd like to set up 3 parameters:
User
Month
Day
But my problem is that when I set up details of parameter and I run it some values are multiplied. Same user is multiplied few times, same month, same day etc. also report itself is not reacting on any kind of change within parameters.
The main idea of a report is to show the number of phone calls done by every employee, each day, every month and to be able to compare results with others.
Calls are splitted into: outgoing and incoming. After every phone call employee adds to system an information regarding what phone call it was and what they managed to do during this phone call.
So in fact we are working on 2 tables in this case:
CaseActionHistory and Users
So the plan was to show the number of phone calls (incoming, outgoing and sum of those) for every day for every person.
Since CaseActionHistory table consits only ID of User which done the action and I'd like to show the person's name (which is placed in Users table obviously).
The problem is that the report should show around 20 Users one by one, so for 31st of June 20 Users one by one, for 30th 20 Users one by one etc, but it shows like 5 Users for 31st, then same Users for 30th, then next 5 Users for 31st etc (link to image showing the situation below)
http://img801.imageshack.us/img801/2088/7blu.png
Columns are:
UserId (to be replaced with UserName) Day Month Incming Outgoing Sum
The rows on the bottom for 31st July should be on the top of the list but they are not.
Welcome to stack overflow. A few things:
If your data is 'multiplying' may you just do a 'distinct' in your main select statement and determine if it is not your dataset repeating?
How are you applying parameters? They should be predicates and have nothing to do with groupings except indirectly. You may limit a set by a parameter but it will not affect your grouping directly, generally speaking.
What do you want to group by? Year, Month, (detail)?
SSRS starts out with a data connection (Data Source). You then apply a Data Set which is a query or proc. Which you have a query. You can apply a predicate to the main dataset with a 'where User = #User' or 'where User in (#User)'. The parameter will automatically be created if you do this in your dataset first with the '#(something)' creating a text parameter of said name. You see the Built In Fields, Parameters, Images, Data Sources, DataSets in the 'Report Data' view which you will use constantly in SSRS creation with 'Business Intelligence Development Studio'.
So a simple example would be that you want to add a group for the Day to your '(Details)' row. If you create a 'Table' element from the 'Toolbox' it will only have a single row called Details. Fill it with your X value and user. In the 'Design' surface at the bottom you will see 'Row Groups'. Right click on your 'Details' row and choose add parent group. Group by 'Day' check 'Add Group Header'. You now have another row that will be grouping by Day. You can repeat this process on the newly created group for a group for 'Month' and so and so on.
Does anyone know how to make it so that when there are multiple records for a month (See image) there is only one line of data rather than splitting it into 4 boxes.
For example see June, I want this to have one box for RFC days and one box for Project days.
I have grouped by so far:
Row Groups - Service, MonthName
Column Groups - classification
You could do it by using grouping and sum the values at the group level and hide the detail line.
However, the easiest thing to do is do it in SQL using nested queries, like so (you probably also want to order by the month number rather than name, as shown below):
SELECT Service, Month(DateField) AS MonthNumber,
MAX(DatePart(Month, DateField)) AS MonthName,
SUM(ProjectDays) AS ProjectDays, SUM(RFCDays) AS RFCDays
FROM (
SELECT Service, DateField, Days AS ProjectDays, 0 AS RFCDays
FROM Project
UNION ALL
SELECT Service, DateField, 0 AS ProjectDays, Days AS RFCDays
FROM RFC
)
GROUP BY Service, Month(DateField)
ORDER BY Service, Month(DateField)
I found that I had to GROUP BY my MONTH field so I dragged this into the group by row groups, right clicked on it from here and in Group Properties added a group expression.
I can get a single count row from a specified date range like this:
SELECT table.[EVENT NAME], Count(*) AS [Count]
FROM table
WHERE [EVENT]='alphabetical' And table.DATE>=#11/20/2010# And (table.DATE)<=#11/26/2010#
GROUP BY table.[EVENT NAME];
but how could I add multiple rows with different date ranges?
[EVENT NAME],[DATE 11/20-11/26],[DATE 11/27-12/3], etc...
EDIT
the data would look something like this
event1;1/11/2010
event1;1/11/2010
event2;1/11/2010
event2;1/11/2010
event2;1/11/2010
event3;1/11/2010
event1;1/12/2010
event1;1/12/2010
event2;1/12/2010
event2;1/12/2010
event4;1/12/2010
event4;1/12/2010
etc.
and would like something like this (preferably with more columns) :
event1;2;2
event2;3;2
event3;1;0
event4;0;2
You'd use a group by clause and group by the date.
You didn't provide example records with expected results, that helps us help you :).
In other words post more information..
But from what I can tell you want a count based on a date range.
So if you had 1/1/2010 with 10 rows
and 1/2/2010 with 20 referenced rows
and 1/3/2010 with 6 reference rows...you'd want output like this:
1/1/2010 10
1/2/2010 20
1/3/2010 6
So SELECT COUNT(*), MyDate FROM MyTable GROUP BY MyDate
To answer your question about a date range, think of how group by works, it works by grouping a set of data by combining all sets that match a criteria. So when you say group by date it groups by a single date. You want a date range, so each row should know about or understand a range (Start to End). So you need to include these columns in each of your rows by generating them via SQL.
Edit
For instance
SELECT Count(*), DATEADD(day, -10, GetDate()) AS StartDate, DATEADD(day, 10, GetDate()) AS EndDate
FROM MyTable GROUP BY StartDate, EndDate
Access has similiar functions to add days to dates so look that up for MS Access. Then just generate a start and end date for each column.