Dynamic Grouping in SSRS 2012 - sql

I am developing a report that have parameter like
RowGroupLevel1,
RowGroupLevel2,
ColumnGroupLevel1,
ColumnGroupLevel2,
ColumnGroupLevel3
Row Group Contain Category, Executive Name, Client Name Like Field
Column Group Contain Year,Quarter,Month Field.
So My requirement is as like except Level1 in Row and Column Grouping other fields are optional.
For An Example : if I am selecting as below
scenario 1 :
RowGroupLevel1 - Category
RowGroupLevel2 - Executive Name
ColumnGroupLevel1 - Year
ColumnGroupLevel2 - Quaker
ColumnGroupLevel3 - Month
scenario 2 :
RowGroupLevel1 - Category
RowGroupLevel2 -
ColumnGroupLevel1 - Year
ColumnGroupLevel2 - Month
ColumnGroupLevel3 -
so as per above scenario how I can grouping my report dynamically.
Please help me to create any type of SSRS report.
Thanks in advance.
Ankit Gusani

The easiest way to achieve this is to first of all write your query which pulls forward the results like this.
SQL Server Query
SELECT DATEPART(WEEK, Date_Column) AS [Weekly]
,DATEPART(MONTH, Date_Column) AS [Monthly]
,DATEPART(YEAR, Date_Column) AS [Yearly]
,SUM(Some_Column) AS Total
FROM Table_Name
GROUP BY DATEPART(MONTH, Date_Column)
,DATEPART(WEEK, Date_Column)
,DATEPART(YEAR, Date_Column)
SSRS Report
Add a Matrix Data region. Drag and drop Total column to DATA.
Create a Parameter say GROUP ON of Text type, and provide values
1) Weekly
2) Monthly
3) Yearly
Now below in ROW GROUPS pane, right click the only visible Row Group and goto GROUP PROPERTIES
In GROUP ON section put following expression.
=SWITCH(
Parameters!Groupby.Value = "Weekly", Fields!Weekly.Value
,Parameters!Groupby.Value = "Monthly", Fields!Monthly.Value
,Parameters!Groupby.Value = "Yearly", Fields!Yearly.Value
)
Use the exactly same Expression on Data region ROWS section.
For Column name you can use the following Expression...
=SWITCH(
Parameters!Groupby.Value = "Weekly", "Weekly"
,Parameters!Groupby.Value = "Monthly", "Monthly"
,Parameters!Groupby.Value = "Yearly", "Yearly"
)
and you are good to go.
Important Note
SSRS is a cool tool for data presentation, not so cool when it comes to Data manipulation, to get better performance do all sorts of Data Manipulation closer to source (database, SQL Server).
All of the presentation stuff should be handled on SSRS.

Related

SQL select & group-by as DAX

I am trying to create a new measure in power BI from my database - i have a table from which i can run a query and get a csv file of the result but want to set the report up to look at up to date data and the csv is only a snapshot.
I count the individual row entries (error occurrences) to create a count of the errors and wish to group these by date (RTO_UPDATED) and location (RTO_BLOCK) for analysis on when and where we are experiencing these errors
This is the code below:
select count(*) as Errors,
cast(RTO_UPDATED as date) as Date,
RTO_BLOCK
FROM [MIS_Apps].[dbo].[LiveRTOLocationErrorsHistorical]
group by cast(RTO_UPDATED as date),
RTO_BLOCK
If someone could help me convert this to DAX it would be greatly appreciated
I have tried this (below) but apparently the evaluate syntax is incorrect and i am unsure how to change it when a group-by is involved?
EVALUATE SELECTCOLUMNS(
count(*) as Errors, cast(RTO_UPDATED as date) as Date, RTO_BLOCK
FROM [MIS_Apps].[dbo].[LiveRTOLocationErrorsHistorical]
group by cast(RTO_UPDATED as date), RTO_BLOCK
)
Try this following with adding a custom table in your Power BI report. Add this below code in the Custom Table generation window.
Group_by_result =
GROUPBY (
// -- This is the table name
LiveRTOLocationErrorsHistorical,
// -- Below two column are GROUP BY columns
LiveRTOLocationErrorsHistorical[RTO_UPDATED],
LiveRTOLocationErrorsHistorical[RTO_BLOCK ],
// -- Here comes the aggregation
"Total_count", COUNTX(CURRENTGROUP(), 1)
)

Sql View : Column Header having dynamic date

I need to do this in excel: 4 column having date of passed week (today is 19-07-2018, so the first will 12-07-2018). the report from Sql is connected via ODBC and when it is opened the column header should consider this range using the current date as a referred day.
I'm not able to find code to insert in the select this dates. If I try in Excel, the report take 2 minutes to refresh data on the sheets. So only idea I have is replicate the report in SQL, having a view. Do you have a solution for me different from declare a variable and execute it, please? I really appreciate it.
(in use Sql 2012)
You can have an imaginary column in your data on the fly that would serve as a "week grouping" column. It contains the "first day of the week". You select your data as "Attribute, WeekGroup, Value" from SQL server and PIVOT this data in Excel (excel really shines in pivoting the data so you don't need to pivot in SQL - pass raw data and pivot there instead). In pivoting "Attribute" is the Row field, "week" go into column field and data is value (probably you would want SUM which is the default, if not specify your calculation).
Here is a sample in SQLFiddle for the data and Query
EDIT: Pasting the query here too just thinking SQLFiddle link may get lost:
WITH dates (d)
AS (SELECT TOP (7 * 4)
DATEADD(d, -7 + ROW_NUMBER() OVER (ORDER BY t1.object_id), CAST(GETDATE() AS DATE))
FROM sys.objects t1,
sys.objects t2),
mondays
AS (SELECT d
FROM dates
WHERE DATENAME(WEEKDAY, d) = 'Monday')
SELECT t.attribute,
m.d AS [week],
t.value
FROM myTable t
INNER JOIN mondays m
ON t.dt >= m.d
AND t.dt < DATEADD(d, 7, m.d)
ORDER BY t.attribute,
d,
dt;

Group by: calculated field to return respective date in bigquery

I need to do an user level analysis. As the data has a lot of different rows per user (related to different events), I need to group by user and create some calculated fields that represent the different rows. One of the fields is a calculation of the number of days since the last purchase of the user (today - last purchase date). I already tried a lot of different codes and also did a lot of research, but could not find the solution.
The codes that for me makes more sense but did not work are below:
Using case when statement
SELECT CASE WHEN LAST(tr_orderid <> "") THEN
DATEDIFF(CURRENT_DATE(),event_date) ELSE NULL END AS recency_lastbooking
FROM df
GROUP BY domain_userid
Using IF statement
SELECT IF(LAST(tr_total > 0), DATEDIFF(CURRENT_DATE(),event_date), NULL)
AS recency_lastbooking
FROM df
GROUP BY domain_userid
The error that I get is: Expression 'event_date' is not present in the GROUP BY list
I think if I use LAST(event_date) the query will return the last date in all the lines of the specific user, instead of return the last day the user had a purchase event.
P.S: I can use tr_total (total transaction) > 0 or tr_orderid (transaction order id) <> ""
Thank you!
I think you just want a window function:
SELECT DATE_DIFF(CURRENT_DATE,
MAX(tr_orderid) OVER (PARTITION BY domain_userid),
day
) AS recency_lastbooking
FROM df;

SQL: Average value per day

I have a database called ‘tweets’. The database 'tweets' includes (amongst others) the rows 'tweet_id', 'created at' (dd/mm/yyyy hh/mm/ss), ‘classified’ and 'processed text'. Within the ‘processed text’ row there are certain strings such as {TICKER|IBM}', to which I will refer as ticker-strings.
My target is to get the average value of ‘classified’ per ticker-string per day. The row ‘classified’ includes the numerical values -1, 0 and 1.
At this moment, I have a working SQL query for the average value of ‘classified’ for one ticker-string per day. See the script below.
SELECT Date( `created_at` ) , AVG( `classified` ) AS Classified
FROM `tweets`
WHERE `processed_text` LIKE '%{TICKER|IBM}%'
GROUP BY Date( `created_at` )
There are however two problems with this script:
It does not include days on which there were zero ‘processed_text’s like {TICKER|IBM}. I would however like it to spit out the value zero in this case.
I have 100+ different ticker-strings and would thus like to have a script which can process multiple strings at the same time. I can also do them manually, one by one, but this would cost me a terrible lot of time.
When I had a similar question for counting the ‘tweet_id’s per ticker-string, somebody else suggested using the following:
SELECT d.date, coalesce(IBM, 0) as IBM, coalesce(GOOG, 0) as GOOG,
coalesce(BAC, 0) AS BAC
FROM dates d LEFT JOIN
(SELECT DATE(created_at) AS date,
COUNT(DISTINCT CASE WHEN processed_text LIKE '%{TICKER|IBM}%' then tweet_id
END) as IBM,
COUNT(DISTINCT CASE WHEN processed_text LIKE '%{TICKER|GOOG}%' then tweet_id
END) as GOOG,
COUNT(DISTINCT CASE WHEN processed_text LIKE '%{TICKER|BAC}%' then tweet_id
END) as BAC
FROM tweets
GROUP BY date
) t
ON d.date = t.date;
This script worked perfectly for counting the tweet_ids per ticker-string. As I however stated, I am not looking to find the average classified scores per ticker-string. My question is therefore: Could someone show me how to adjust this script in such a way that I can calculate the average classified scores per ticker-string per day?
SELECT d.date, t.ticker, COALESCE(COUNT(DISTINCT tweet_id), 0) AS tweets
FROM dates d
LEFT JOIN
(SELECT DATE(created_at) AS date,
SUBSTR(processed_text,
LOCATE('{TICKER|', processed_text) + 8,
LOCATE('}', processed_text, LOCATE('{TICKER|', processed_text))
- LOCATE('{TICKER|', processed_text) - 8)) t
ON d.date = t.date
GROUP BY d.date, t.ticker
This will put each ticker on its own row, not a column. If you want them moved to columns, you have to pivot the result. How you do this depends on the DBMS. Some have built-in features for creating pivot tables. Others (e.g. MySQL) do not and you have to write tricky code to do it; if you know all the possible values ahead of time, it's not too hard, but if they can change you have to write dynamic SQL in a stored procedure.
See MySQL pivot table for how to do it in MySQL.

View data by date after Format 'mmyy'

I'm trying to answer questions like, how many POs per month do we have? Or, how many lines are there in every PO by month, etc. The original PO dates are all formatted #1/1/2013#. So my first step was to Format each PO record date into 'mmyy' so I could group and COUNT them.
This worked well but, now I cannot view the data by date... For example, I cannot ask 'How many POs after December did we get?' I think this is because SQL does not recognize mm/yy as a comparable date.
Any ideas how I could restructure this?
There are 2 queries I wrote. This is the query to format the dates. This is also the query I was trying to add the date filter to (ex: >#3/14#)
SELECT qryALL_PO.POLN, Format([PO CREATE DATE],"mm/yy") AS [Date]
FROM qryALL_PO
GROUP BY qryALL_PO.POLN, Format([PO CREATE DATE],"mm/yy");
My group and counting query is:
SELECT qryALL_PO.POLN, Sum(qryALL_PO.[LINE QUANTITY]) AS SUM_QTY_PO
FROM qryALL_PO
GROUP BY qryALL_PO.POLN;
You can still count and group dates, as long as you have a way to determine the part of the date you are looking for.
In Access you can use year and month for example to get the year and month part of the date:
select year(mydate)
, month(mydate)
, count(*)
from tableX
group
by year(mydate)
, month(mydate)
You can format it 'YYYY-MM' , and then use '>' for 'after' clause