Get value from Measure in OLAP Cube and Insert it in a SQL table - tsql

I need help with the the following:
I got an OLAP Cube, let's call it "company_prod" on "server\instance"
That Cube has (among many) a calculated member called "[Measures].[Value]"
One of the Dimensions in the Cube is for time (Year, Month, Date and so on). e.g. [TIME].[Y_M_D].[YEAR].&[2020]
Our main frontend is Excel, where we retrieve Data from the Cube with CUBEELEMENT, CUBEVALUE etc.
We got some measures which unfortunately, when I update the Excel report now and show numbers for last year, the result is different when I update that same report in a few weeks or months. This is something I won't be able to change and in some reports it's the desired behaviour because underlying data from SAP is changed and sometimes valid_from and valid_to dates are changed retroactively.
Now I want to get the value from my "[Measures].[Value]" on a certain date, let's say April 1st. I then want to insert the value I get on April 1st for 2020 in a SQL table. This should be done by an agent job that executes a stored procedure or runs a dtsx package or anything else, whichever works.
I hope it's clear what I am trying to accomplish...

If you can create linked servers from your SQL Server to SSAS Server, then you can run your MDX query against the linked SSAS Server using OPENQUERY and save the result directly to the SQL Server table.
i.e.,
INSERT INTO <your table>
EXECUTE <your mdx statement> AT <linked server>
You can add the run the above via your SQL Agent job on schedule.

Related

Inaccurate COUNT DISTINCT Aggregation with Date dimension in Google Data Studio

When I aggregate values in Google Data Studio with a date dimension on a PostgreSQL Connector, I see buggy behaviour. The symptom is that performing COUNT(DISTINCT) returns the same value as COUNT():
My theory is that it has something to do with the aggregation on the data occurring after the count has already happened. If I attempt the exact same aggregation on the same data in an exported CSV instead of directly from a PostgreSQL Connector Data Source, the issue does not reproduce:
My PostgreSQL Connector is connecting to Amazon Redshift (jdbc:postgresql://*******.eu-west-1.redshift.amazonaws.com) with the following custom query:
SELECT
userid,
submissionid,
date
FROM mytable
Workaround
If I stop using the default date field for the Date Dimension and aggregate my own dates directly in within the SQL query (date_byweek), the COUNT(DISTINCT) aggregation works as expected:
SELECT
userid,
submissionid,
to_char(date,'YYYY-IW') as date_byweek
FROM mytable
While this workaround solves my immediate problem, it sucks because I miss out on all the date functionality provided by Data Studio (Hierarchy Drill Down, Date Range filtering, etc.). Not to mention reducing my confidence at what else may be "buggy" within the product 😞
How to Reproduce
If you'd like to re-create the issue, using the following data as a PostgreSQL Data Source should suffice:
> SELECT * FROM mytable
userid submissionid
-------- -------------
1 1
2 2
1 3
1 4
3 5
> COUNT(DISTINCT userid) -- ERROR: Returns 5 when data source is PostgreSQL
> COUNT(DISTINCT userid) -- EXPECTED: Returns 3 when data source is CSV (exported from same PostgreSQL query above)
I'm happy to report that as of Sep 17 2020, there's a workaround.
DataStudio added the DATETIME_TRUNC function (see here https://support.google.com/datastudio/answer/9729685?), that allows you to add a custom field that truncs the original date to whatever granularity you want, without causing the distinct bug.
Attempting to set the display granularity in the report still causes the bug (i.e., you'll still set Oct 1 2020 12:00:00 instead of Oct 2020).
This can be solved by creating a SECOND custom field, which just returns the first, and then you can add IT to the report, change the display granularity, and everything will work OK.
I have the same issue with MySQL Connector. But my problem is solved, when I change date field format in DB from DATETIME (YYYY-MM-DD HH:MM:SS) to INT (Unixtimestamp). After connection this table to the Googe Datastudio I set type for this field as Date (YYYYMMDD) and all works, as expected. Hope, this may help you :)
In this Google forum there is a curious solution by Damien Choizit that involves combining your data source with itself. It works well for me.
https://support.google.com/datastudio/thread/13600719?hl=en&msgid=39060607
It says:
I figured out a solution in my case: I used a Blend Data joining twice the same data source with corresponding join key(s), then I specified a data range dimension only on the left side and selected the columns I wanted to CTD aggregate as "dimensions" (and not metric!) on the right side.

ssrs/ssrb end user picks a date to filter by

I'm using sql server 2008 r2 and i'm new to building reports with ssrs. I have the reports built, but i'm trying to make it so when the end user, goes to the report on the site, they are able to pick a start and end date. So the data gets filtered by those, to look at it each quarter.
I've been looking through the interwebs for a few hours and it looks like people are able to do this, but i haven't seen anything on how yet.
Also i see there is a date picker thats greyed out, but I've read that it can only be used in web projects, is that what I'm looking for?
I don't have 2008 but in 2012 you would simply define 2 parameters as date/time and amend your dataset to include them. For example
SELECT SalesOrderID, OrderDate, Status, TotalDue
FROM Sales.SalesOrderHeader
where orderdate between #lodate and #hidate
The datasource in this case is advicentureworks2012.
SSRS automatically adds the parameters to the report and includes a date picker.

Crystal Reports 10: Is it possible to call a custom function from a command

I have created 4 custom functions in Crystal Reports 10. These take as input a date-time value from a DB record, and determine whether that date-time falls inside the current Fiscal Year or the previous Fiscal Year.
These calculations were previously executed as stored procedures on an SQL Server but we are moving to another ticketing application (hosted at a vendor site) and do not currently have DB to do these calculations on.
Here is an example of one of these functions:
// Function name: isCloseDateWithinCurrentFY
Function (DateTimeVar closeTime)
// This replaces dbo.fn_FiscalYear
// Determine if the incident close date falls inside the current Fiscal Year
DateTimeVar startCurrentFiscalYear;
NumberVar currentMonth;
StringVar returnVal;
currentMonth := Month(CurrentDate);
If currentMonth >= 2 Then
startCurrentFiscalYear := Date(Year(CurrentDate), 2, 1)
Else
startCurrentFiscalYear := Date(Year(CurrentDate)-1, 2, 1);
If (closeTime >= startCurrentFiscalYear) Then
"T"
Else
"F";
When these calculations were on the SQL Server, they were utilized from a Crystal Report SQL command
SELECT
category,
subcategory,
close_time,
tyCount
FROM (
SELECT
category=ISNULL(UPPER(category),'*Unspecified'),
subcategory=ISNULL(UPPER(subcategory),'*Unspecified'),
tyCount=SUM(CASE WHEN dbo.fn_FiscalYear(close_time)='T' THEN 1 ELSE 0 END)
FROM
incident_tickets
GROUP BY
UPPER(category),
UPPER(subcategory)
) tickets
WHERE
tycmCount>0
ORDER BY
category,
subcategory
In my case I would like to replace the call to dbo.fn_FiscalYear with a call to my custom function isCloseDateWithinCurrentFY.
But is it possible to call a custom function from an SQL command?
Or is there some other way to restrict the returned records based on a calculation made on Crystal Report side?
TIA
No, you cannot use any sort of Crystal code in a SQL command since they're two completely different beasts. The SQL Command is basically just the query that Crystal will send straight to the database in order to get the records to process, after which point those records will be available to use with Crystal code. The SQL server has no way to interpret the Crystal function and Crystal has no way of translating it into SQL.
The easiest way to do this would probably be to just replace dbo.fn_FiscalYear with more SQL hard-coded directly into the query. More specifically, translate isCloseDateWithinCurrentFY into the equivalent SQL.

SSRS 2008 - Multiple Groupings For Date Range

A record in a table contains a range of valid dates, say:
*tbl1.start_date* and *tbl1.end_date*. So to ensure I get all records that are valid for a specific date range, the selection logic is: <...> WHERE end_date >= #dtFrom AND start_date < #dtTo (the #dtTo parameter used in the SQL statement is actually the calculated next day of the *#prmDt_To* parameter used in the report).
Now in a report I need to count the number of records for each day within the specified data range and include the days, if any, for which there were no valid records. Thus a retrieved record may be counted in several different days. I can do it relatively easily with a recursive CTE within the data set, but my rule of thumb is to avoid the unnecessary load on the SQL database and instead return just the necessary raw data and let the Report engine handle groupings. So is there a means to do this within SSRS?
Thank you,
Sergey
You might be able to do something in SSRS with custom code, but I recommend against it. The place to do this is in the dataset. SSRS is not designed to fill in groups that don't exist in the dataset. That sounds like what you are trying to do: SSRS would need to create the groups for each date whether or not that date is in the dataset.
If you don't have a number or date table in your database, I would just create a recursive CTE with a record for every date in the range that you are interested as you mention. Then outer join this to your table and use COUNT(tbl1.start_date) to find the appropriate days. This shouldn't be too painful a query for SQL server.
If you really need to avoid the CTE, then I would create a date or number table to use to generate the dates in your range.

No data returned in Crystal Reports

I have a Crystal Report I'm working on; last week it was returning results but when I fired it up this morning I was no longer getting anything. Checking the SQL query, I show that the table name is listed twice, for some reason:
SELECT "WMS_TESTINFO"."RECORD_NAME"
FROM "TestEnv"."dbo"."WMS_TESTINFO" "WMS_TESTINFO"
Any thoughts on what could have broken? I've checked that the database is connected and my data is still there.
The table name is listed twice as Crystal Reports creates an alias for every table.
This Crystal generated SQL:
FROM "TestEnv"."dbo"."WMS_TESTINFO" "WMS_TESTINFO"
Is in the format of:
FROM DATABASE.OWNER.TABLENAME ALIAS
This is normal for Crystal.
I would run that SQL in SSMS (remembering to remove all of the " first) to check that the data really is still there.
If it is, check that a filter hasn't been added to the report, via the Select Expert menu opton, to filter out all the data.
Lastly, go to Database > Set Datasource Location and re-apply the connection to ensure that the report is definitely pointing at the right location.