ssas mdx and t-sql gives different values - tsql

My situation:
There is a work database. Every day it is copied to another database named RetailDB.
Fact and dimension tables of SSAS are based on VIEW-objects of tables in RetailDB.
So, I have the problem:
MDX query:
SELECT {[Date].[Y-M-D].[Day].[01.01.2013]} ON 0,
{ [Measures].[Quantity]} ON 1
FROM [Company]
gives me NULL value
at the same time t-sql query:
SELECT SUM([Quantity])
FROM [RetailDB].[dbo].[fact_Income]
WHERE Day = '2013-01-01'
gives me 7937338,023
On other date MDX-query can return correct value.
On some other date MDX-query can return not NULL value but it does not equal to t-sql value.
Please, help to correct this problem. What should I check in my cube to fix this?
Thanks for everyones answer.

If you are using the right date dimension, then it would indicate that you need to process the cube to synchronise with your database.
Try bringing back all quantity / dates to see if the data appears to have processed up to a certain point
SELECT {[Measures].[Quantity]} ON 0,
{ [Date].[Y-M-D].[Day]} ON 1
FROM [Company]

Related

SQL Server 2012 : query for finding Minimum and Maximum time based on the group and time window

I have a table with date and time data like below.
I want to collect the data of employee/section/date/time window wise min and max date/time which are bold in the above table. Below table is the result that I want to derive from the above table.
Is there any SQL query options are available to get this?
Thanks in Advance
You can use min,maxandgroup by` functions for your desired result:
select EmpId,Section,min(EntryTime)MinEntryTime,Max(EntryTime)MaxEntryTime
from yourtable
group by EmpId,Section

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.

Identifying next closest record by date in tableau

I have a table of users and another table of transactions.
The transactions all have a date against them. What I am trying to ascertain for each user is the average time between transactions.
User | Transaction Date
-----+-----------------
A | 2001-01-01
A | 2001-01-10
A | 2001-01-12
Consider the above transactions for user A. I am basically looking for the distance from one transaction to the next chronologically to determine the distances.
There are 9 days between transactions one and two; and there are 2 days between transactions three and four. The average of these is obviously 4.5, so I would want to identify the average time between user A's transactions to be 4.5 days.
Any idea of how to achieve this in Tableau?
I am trying to create a calculated field for each transaction to identify the date of the "next" transaction but I am struggling.
{ FIXED [user id] : MIN(IF [Transaction Date] > **this transaction date** THEN [Transaction Date]) }
I am not sure what to replace this transaction date with or whether this is the right approach at all.
Any advice would be greatly appreciated.
LODs dont have access to previous values directly, so you need to create a self join in your data connection. Follow below steps to achieve what you want.
Create a self join with your data with following criteria
Create an LOD calculation as below
{FIXED [User],[Transaction Date]:
MIN(DATEDIFF('day',[Transaction Date],[Transaction Date (Data1)]))
}
Build the View
PS: If you want to improve the performance, Custom SQL might be the way.
The only type of calculation that can take order sequence into account (e.g., when the value for a calculated field depends on the value of the immediately preceding row) is a table calc. You can't use an LOD calc for this kind of problem.
You'll need to understand how partitioning and addressing works with table calcs, along with specifying your sort order criteria. See the online help. You can then do something like, for example, define days_since_last_transaction as:
if first() > 0 then min([Transaction Date]) -
lookup(min([Transaction Date]), -1) end
If you have very large data or for other reasons want to do your calculations at the database instead of in Tableau by a table calc, then you use SQL windowing (aka analytical) queries instead via Tableau's custom SQL.
Please attach an example workbook and anything you tried along with the error you have.
This might not be useful if you cannot set User ID Field as a filter.
So, you can set
User ID
as a filter. Then following the steps mentioned in here will lead you to calculating difference between any two dates. Ideally if you select any one value in the filter, the calculated field from the link should give you the difference in the dates that you have in the transaction dates column.

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.

Want to get the MAX(ID) from a db table datewise, but it returns only same ID in sqlserver 2008 r2

I am trying to get the maximum ID from a database table and want to show it on win form load.
I am using the following query to get the maximum ID.
SELECT ISNULL(MAX(ID),0)+1 FROM StockMain WHERE VRDATE = '2013-01-30'
Above should have to return the maximum ID of today., e.g if I this statement is excutes for the first time it will return me the Value '1'. After saving first record on ID = '1' it should give me MAX(ID) = '2'. But it returns me the value 1.
Any suggestion or solutions????
Wild guess... but what data type is VRDATE? Does it include a time component, or is it just a date?
If it includes a time component indicating when you saved the record, it won't pass the VRDATE = '2013-01-30' check, since this defaults to a time of midnight. Since the times aren't identical, they are not equal.
Instead, try:
SELECT ISNULL(MAX(ID),0)+1
FROM StockMain
WHERE VRDATE BETWEEN '2013-01-30' AND '2013-02-01'
Next question... have you considered using an IDENTITY column instead of managing the ID values manually?