Simple query conversion from sql to mdx - sql

select MAX(InsertionDT),TaskStatus,tasksubstatus
from TransTasksFFMS_GVT
where TaskCode = 323155 group by TaskStatus,tasksubstatus
To use this query in the cube browser I have created a name query and used it as a dimension and it works, however I'm asked to do the calculation as a measure. Is it possible to translate this query to mdx to use it as the expression in a calculation?
What the query does: Returns the max insertion date for a each pair of status and sub status.
I'm new to MDX and to the whole cube idea!

Yes, first make the whole thing a star schema with a fact table/view and a dimension table for the tasks containing Task code, status, and substatus. Then define a measure for the InsertionDt using Max as the aggregation function.

Related

Is it possible to use SQL functions in SQL Kata join conditions?

I try to use SQLKata with SQL Server for the following use case:
Group turnover data per day/week/month/year for a configurable interval. As I also need to include the time units without any turnover data I chose to join this with a table valued function that returns a set of dates (see this link for more info about this SQL Server range of dates)
I query the table valued function in a CTE and would like to left join it with my turnover data. In order to do so I would need to use functions in the join condition though as the dates of the turnover data are more granular than the dates from the DateRange function.
As I have not seen an example in the SQL Kata documentation using a function in a join condition and trying it out gave an error too I guess it's not possible to do it like this.
What I tried:
Include a function in the join condition to reduce some details from the turnover date objects
Use 2 CTES like this: new Query().With(...).With(...) but it complained about the empty base query
What would be the best approach to implement this in a query?

In Access create a calculated column called order based on a column of dates

in Microsoft Access I need to bind a cross-tab query to a report. To bind the query I need to know the column names in advance which is the problem as I do not know which dates will be in the data. The date names end up as the columns in the cross-tab query. as the dates vary the column names vary and I can't bind the report as I don't know the column names. the best solution I can think of is to calculate a column that replaces the date with its order. then the column names will always be 1,2,3,4,5,6,7,8. However I haven't been able to create this calculated order column. No matter what I do access bugs out. Part of the cause is that This table will be used for a cross-tab query with parameters so access bugs out with any additional complications.
How do I turn StatusDate into CalculatedOrder?
Edit:
I cannot use a subquery to make CalculatedOrder as is sujested in the comments because the original query has parameters. access bugs out when a subquery draws on a query based on parameters.
The real problem was two bugs in Access. My guess is Access will bug at any additional complexity. if the original table has parameters work with a copy of the table that doesn't have parameters. In all cases, before calculating the crosstab, copy just your values into another temporary table. In Access, crosstab doesn't work if a crosstab column variable is a correlated subquery.
You can make the CalculatedOrder column using a correlated subquery similar to allenbrowne.com/ranking.html.
if the table has parameters:
PARAMETERS myfirstparameter
SELECT StatusDate, CrossTabRow, CrossTabValue INTO NoParametersTable
FROM MyTableWithParameters
WHERE ...
Then make a query with only a grouped StatusDate.
SELECT NoParametersTable.StatusDate
FROM NoParametersTable
GROUP BY NoParametersTable.StatusDate;
Then Turn StatusDate into Order using a correlatedsubquery:
SELECT CrossTabRow, CrossTabValue, (SELECT Count(dupe.StatusDate) +1 FROM [MyGroupedStatusDateQuery] as dupe WHERE dupe.StatusDate < [MyGroupedStatusDateQuery].StatusDate) AS [Order]
FROM NoParametersTable INNER JOIN [MyGroupedStatusDateQuery] ON NoParametersTable.StatusDate = MyGroupedStatusDateQuery.StatusDate)
finally make sure to turn this final query into a table without a correlatedsubquery by copying the values into another temporary table. run the crosstab on the final temporary table and the crosstab will work because the final table just has values instead of parameters and a correlated subquery.

Dax Queries in ssas

What's wrong in the below code
DEFINE
MEASURE DimDate[MyMeasure] =
COUNTROWS(DimDate)
EVALUATE DimDate[MyMeasure]
I'm getting the following error while running the query:
Query (1, 1) The expression specified in the query is not a valid table expression
Your DAX query must evaluate to a table when you are using DAX as a query language.
E.g. this query is valid because it returns a table with one column and one row:
DEFINE MEASURE DimDate[MyMeasure] = COUNTROWS(DimDate)
EVALUATE
ROW("MyColumn", DimDate[MyMeasure])
But this query will fail because it returns a scalar value instead of a table:
DEFINE MEASURE DimDate[MyMeasure] = COUNTROWS(DimDate)
EVALUATE DimDate[MyMeasure]
You can find the syntax documentation from Microsoft here.
Please note that this is different from defining measures or calculated columns inside a tabular model. Expressions for measures or calculated columns should always evaluate to a scalar value.

Microsoft Access SQL STDEV of COUNT of data

I have a table in MS Access 2010 I'm trying to analyze of people who belong to various groups having completed various jobs. What I would like to do is calculate the standard deviation of the count of the number of jobs each person has completed per group. Meaning, the output I would like is that for each group, I'd have a number that constitutes the standard deviation of how many jobs each person did.
The data is structured like this:
OldGroup, OldPerson, JobID
I know that I need to do a COUNT of the job IDs by Group and Person. I tried creating a subquery to work with, but that didn't work:
SELECT data.OldGroup, STDEV(
SELECT COUNT(data.JobID)
FROM data
WHERE data.Classification = 1
GROUP BY data.OldGroup, data.OldPerson
)
FROM data
GROUP BY data.OldGroup;
This returned an error "At most one record can be returned by this subquery," which I know is wrong, since when I tried to run the subquery as a standalone query it successfully returned more than one record.
Question:
How can I get the STDEV of a COUNT?
Subquestion: If this question can be answered by correcting incorrect syntax in my examples, please do so.
A minor change in strategy that wouldn't work for all cases but did end up working for this one seemed to take care of the problem. Instead of sticking the subquery in the SELECT statement, I put it in FROM, mimicking creating a separate table.
As such, my code looks like:
SELECT OldGroup, STDEV(NumberJobs) AS JobsStDev
FROM (
SELECT OldGroup, OldPerson, COUNT(JobID) AS NumberJobs
FROM data
WHERE data.Classification = 1
GROUP BY OldGroup, OldPerson
) AS TempTable
GROUP BY OldGroup;
That seemed to get the job done.
Try doing a max table query for "SELECT COUNT(data.JobID)...."
Then for the 2nd query, use the new base table.
Sometimes it is just easier to do something in 2 or more queries.

Why can't I perform an aggregate function on an expression containing an aggregate but I can do so by creating a new select statement around it?

Why is it that in SQL Server I can't do this:
select sum(count(id)) as 'count'
from table
But I can do
select sum(x.count)
from
(
select count(id) as 'count'
from table
) x
Are they not essentially the same thing? How am I meant to be thinking about this in order to understand why the first block of code isn't allowed?
SUM() in your example is a no-op - SUM() of a COUNT() means the same as just COUNT(). So neither of your example queries appear to do anything useful.
It seems to me that nesting aggregates would only make sense if you wanted to apply two different aggregations - meaning GROUP BY on different sets of columns. To specify two different aggregations you would need to use the GROUPING SETS feature or SUM() OVER feature. Maybe if you explain what you want to achieve someone could show you how.
The gist of the issue is that there is no such concept as aggregate of an aggregate applied to a relation, see Aggregation. Having such a concept would leave too many holes in the definition and makes the GROUP BY clause impossible to express: it needs to define both the inner aggregate GROUP BY clause and the outer aggregate as well! This applies also to the other aggregate attributes, like the HAVING clause.
However, the result of an aggregate applied to a relation is another relation, and this result relation in turn can support a new aggregate operator. This explains why you can aggregate the result into an outer SELECT. This leaves no ambiguity in the definition, each SELECT has its own distinct GROUP BY/HAVING clauses.
In simple terms, aggregation functions operate over a column and generate a scalar value, hence they cannot be applied over their result. When you create a select statement over a scalar value you transform it into an artificial column, that's why it can be used by an aggregation function again.
Please note that most of the times there's no point in applying an aggregation function over the result of another aggregation function: in your sample sum(count(id)) == count(id).
i would like to know what your expected result in this sql
select sum(count(id)) as 'count'
from table
when you use the count function, only 1 result(total count) will be return. So, may i ask why you want to sum the only 1 result.
You will surely got the error because an aggregate function cannot perform on an expression containing an aggregate or a subquery.
It's working for me using SQLFiddle, not sure why it would't work for you. But I do have an explanation as to why it might not be working for you and why the alternative would work...
Your example is using a keyword as a column name, that may not always work. But when the column is only in a sub expression, the query engine is free to discard the name (in fact it probaly does) so the fact that it potentially potentially conflicts with a key word may be disregarded.
EDIT: in response to your edit/comment. No, the two aren't equivalent. The RESULT would be equivalent, but the process of getting to that result is not at all similar. For the first to work, the parser has do some work that simply doesn't make sense for it to do (applying an aggregate to a single value, either on a row by row basis or as), in the second case, an aggregate is applied to a table. The fact that the table is a temporary virtual table will be unimportant to the aggregate function.
I think you can write the sql query, which produces 'count' of rows for the required output. Functions do not take aggregated functions like 'sum' or aggregated subquery. My problem was resolved by using a simple sql query to get the count out....
Microsoft SQL Server doesn’t support it.
You can get around this problem by using a Derived table:
select sum(x.count)
from
(
select count(id) as 'count'
from table
) x
On the other hand using the below code will give you an error message.
select sum(count(id)) as 'count'
from table
Cannot perform an aggregate function on an expression containing an
aggregate or a subquery