Dax Queries in ssas - 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.

Related

SQL 2 HAVING syntax

My professor is teaching sql 2, and used an statement like the code below into a query:
HAVING SUM(column) > subselect
Where subselect is something like SELECT AVG(column) FROM ...
This subselect returns only one value, but I could not understand how is it possible to compare a function (the sum) with a subselect. The subselect should return a table, right? Then how is it possible to compare a table with a value? That did not make sense to me.
Thanks in advance.
SQL has a concept of scalar subqueries. These are subqueries that return exactly one column and at most one row. Scalar subqueries can be used in almost all cases where a single value ("scalar") can be used.
If the scalar subquery returns no rows, then the value is treated as NULL.
(I should add that some databases support tuples. A tuple is a set of scalar values that is treated as a single value. In such databases "scalar" subqueries can return more than one value, but these are converted to a tuple. This is not relevant to the question being asked; tuples are just another example of a "single" value.)
In principle you are right, if you look at it in a relational way.
But SQL is an industry standard and allows the abbreviation of comparing a scalar value with a result table with only a single row and column.
Depending on the exact implementation, it even allows to compare a scalar with a list of values (a column with more than one value), although you actually should write ... value > ALL (subselect), it is often accepted without the ALL keyword.
This is both valid syntax in the where and in the having clause

Best practice for constant value in the WHERE clause?

I have a where clause that compares two columns to the following string. Does this concatenation run for every row? Should this string (and concatenation) be left in twice or should I create a variable to hold the result and use that in the WHERE clause?
CONCAT('%', #myVar, 'dr')
I checked the Execution Plan for your expression in a test table present in my database. The table has two nvarchar(50) columns namely firstname and fullname .
I can clearly see that even for three AND conditions in where clause that I put deliberately, the SQL Server engine is showing 0% cost for both the compute scalar steps. It is clearly evident of the fact that irrespective of whether you create a separate variable for the concatenation expression or leave it in-line in your where clause it is not going to make any difference.
Create a variable to hold the result and use that in the WHERE clause

SQL clause vs expression terms

I had a discussion with a teammate on the topic whether the terms clause and expression can be used interchangeably. For example, is it correct/common to call a variable that stands for an expression a=b (e.g. that participates in a statement SELECT * WHERE expression) a clause?
Edit
It would be useful is someone could give precise definitions of what clause, expression and statement are in SQL world.
In SQL Terms, "clause" is usually used to refer to a section of a statement, usually introduced by the keyword it's named after - e.g. a typical SELECT statement would be composed of a SELECT clause, a FROM clause and a WHERE clause. Within the FROM clause, some people may refer to JOIN clauses and ON clauses. However, this is by no means 100% accepted usage.
When it comes to "statement" and "expression", it's fairly standard usage - an expression is something that produces a value. In most languages, this is understood, further, to be something that produces a scalar value. In SQL, this is slightly modified because when you encounter an expression when working with a row set, the expression will produce one scalar value per row (or per group or partition, if grouping or partitioning are involved and it's in the relevant location).
Finally, a statement is a complete "something" that your database engine can understand and produce results for. It doesn't produce a value but it may produce a result set. You can't just send a FROM clause to the database - it has to be part of a larger statement, such as the SELECT statement I mentioned in my first paragraph.
The answer is NO, expression evaluates to something may be a boolean value or string or number where as a clause forms a rule for the data to satisfy and only then the record forms part of the result.
select * from TABLE where /*clause 1*/ field1 = field2
and /*clause 2*/field3 = /*expression*/ field1 + field2
In the above select statement
first clause forms a rule which is field1 should be equal to field2
Second clause form a rule which is field3 should be equal to the result of the > expression field1 + field2
UPDATE
There are various clauses in SQL like from, where, order by, group by and having. from clause tells from which table to read and order by tells how to arrange the result. Clauses control from where data to be read, what data be formed as part of the select statement and how the data to be presented.
Expression on the other hand evaluate to a value of some datatype.
A Statement, is a structured query build with the clauses.

Simple query conversion from sql to mdx

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.

Converting SQL statement to SQL expression field in Crystal Reports

I have a SQL statement that pulls data I need but I can't get the syntax right in Crystal Reports.
This statement works in SQL:
SELECT
max([meter_reading])
FROM [Forefront].[dbo].[EC_METER_HISTORY_MC]
WHERE [Meter_Number] = '1' AND [Transaction_Date] < '20130101'
GROUP BY
[Company_Code], [Equipment_Code], [Meter_Number]
This is what I changed it to in crystal but I can't get the right syntax.
SELECT
Maximum({EC_METER_HISTORY_MC.meter_reading})
FROM [EC_METER_HISTORY_MC]
WHERE {EC_METER_HISTORY_MC.Meter_Number} = '1'
AND {EC_METER_HISTORY_MC.Transaction_Date} < {1?Startdate}
GROUP BY {EC_METER_HISTORY_MC.Company_Code}
,{EC_METER_HISTORY_MC.Equipment_Code}
,{EC_METER_HISTORY_MC.Meter_Number}
Your first step should be reading up on how SQL Expressions work in Crystal. Here is a good link to get you started.
A few of your problems include:
Using a parameter field. SQL Expressions are not compatible with CR
parameters and cannot be used in them.
SQL Expressions can only return scalar values per row of your report. That means that your
use of GROUP BY doesn't serve any purpose.
Your use of curly braces means that you're referencing those fields in the main report query instead of in the subquery you're trying to create with this expression.
Here's a simplified example that would find the max meter reading of a particular meter (for Oracle since that's what I know and you didn't specify which DB you're using):
case when {EC_METER_HISTORY_MC.Meter_Number} is null then null
else (select max(Meter_Reading)
from EC_METER_HISTORY_MC
where Meter_Number={EC_METER_HISTORY_MC.Meter_Number} --filter by the meter number from main query
and Transaction_Date < Current_Date) --filter by some date. CAN'T use parameter here.
end
You can't use parameter fields in a SQL Expression, sadly. Perhaps you can correlate the Transaction_Date to a table in the main query. Otherwise, I would suggest using a Command.
You have two options for the Command:
Use a single Command object as the data source for the whole report--which involves (potentially) a fair amount of rework.
Add a Command to the existing table set (in the Database 'Expert'). Link it to other tables as desired. This will perform a second SELECT and join the results in memory (WhileReadingRecords, if I'm not mistaken). The slight performance hit may we worth the benefit.