DAX IF ELSE statement performance issue - powerpivot

Sales := CALCULATE(
IF(HASONEVALUE('SalesTable'[Sales]),CALCULATE(VALUES('SalesTable'[Sales]))),
LASTNONBLANK('SalesTable'[Date],1))
The above query work fine. When I filter by month, it will shows my last sales 20000 for January, then when I filter 20170103, it will show me nothing because 20170103 has two values which is not valid. I would like to ask if there is any way I can improve this query for better browsing performance

Related

Determining Depreciation by Fiscal Year in PeopleSoft Query Manager

I apologize if this has been covered somewhere, but I haven't found anything that quite meets my specific needs. In PeopleSoft Query Manager, we are trying to build a report that projects depreciation 5 or so years into the future. We want the columns to be the fiscal year and we want the returned values to be the annual depreciation by asset by business unit.
What we've tried so far is creating an aggregate expression that will sum the asset depreciation. This simple expression works in and of itself as it sums the monthly depreciation by asset. However, what we'd like to do is create 5+ columns with 5+ of these aggregate sum expressions, based on the fiscal year. So the first "numerical data" column would show 2019's depreciation, the second would show 2020's and so on.
Now, let me provide a disclaimer and say I'm an accountant and not a code person, so I'm less than a novice here. But we've tried embedding the aggregate sum function with case or decode and we have been unable to get it to work with any such conditional type functions. However, surely there must be a way? (For potential further clarity, if we had the data in excel we would use something like =SUMIFS(Depreciation column, fiscal year column, 2019) and then repeat that for the remaining years. We want to get this same result directly from the query though).
Below, we have two codes. The simple one that works but doesn't provide what we need exactly and the one with conditional functions that we can't quite get to work.
`SELECT A.BUSINESS_UNIT, A.ASSET_ID, sum( A.DEPR)
FROM PS_DEPR_RPT A
WHERE ( A.BOOK = 'CORPORATE'
AND A.BUSINESS_UNIT = '50226')
GROUP BY A.BUSINESS_UNIT, A.ASSET_ID
HAVING ( sum( A.DEPR) <> 0)`
`SELECT A.BUSINESS_UNIT, A.ASSET_ID, CASE
WHEN A.FISCAL_YEAR = 2019 THEN sum( A.DEPR)
END
FROM PS_DEPR_RPT A
WHERE ( A.BOOK = 'CORPORATE'
AND A.BUSINESS_UNIT = '50226')
GROUP BY A.BUSINESS_UNIT, A.ASSET_ID
HAVING ( CASE
WHEN A.FISCAL_YEAR = 2019 THEN sum( A.DEPR)
END <> 0)`
The first one works fine but does not have the necessary fiscal year information. Now, yes, we can use the fiscal year field as a criteria and then build an excel file using sumifs or other such formulas. But we really would like to not have to manipulate the data in excel, and it seems like we should be able to create this in PeopleSoft Query Manager.
Obviously, the second one looks off (I imagine people who are knowledgeable about SQL are banging their heads), and we get this error:
Error in running query because of SQL Error, Code=979, Message=ORA-00979: not a GROUP BY expression (50,380)
(In my preliminary research, it seems like the group by expression error was a common recurrence when using these conditional functions with aggregate functions).
Lastly, please keep in mind that I personally don't have the ability to create SQL that I could put into the system. The SQL is what query manager generates and my only ability to change it is by using expressions and criteria changes.
EDIT for current results and preferred results:
What It Looks Like As Is
What We Want It To Look Like
Thanks in advance!

Qlik sense only show values on trend graph

I have a trend graph line..and these values show as time differences for orders per customers
This is the sort of question to ask how to stop showing 0 however
This measure is worked out using an if statement.. within the if statement there is sum difference between two time stamps.
if("CheckDate" < StartCheckDate , max({$<[Temperature]={'<=0'}>} CheckDate) - min({$<[Temperature]={'>0'}, CheckNumber = {1}>} CheckDate), max({$<[Temperature]={'<=0'}>} CheckDate) - min({$<[Temperature]={'>0'}, CheckNumber = {2}>} CheckDate))
However some customers are showing up as 00:00:00 how do I in the measure say don't show these customers.. that have 00:00:00
please help..

SQL Statement - want daily dates rolled up and displayed as Year

I have two years worth of data that I'm summing up for instance
Date | Ingredient_cost_Amount| Cost_Share_amount |
I'm looking at two years worth of data for 2012 and 2013,
I want to roll up all the totals so I have only two rows, one row for 2012 and one row for 2013. How do I write a SQL statement that will look at the dates but display only the 4 digit year vs 8 digit daily date. I suspect the sum piece of it will be taken care of by summing those columns withe calculations, so I'm really looking for help in how to tranpose a daily date to a 4 digit year.
Help is greatly appreciated.
select DATEPART(year,[Date]) [Year]
, sum(Ingredient_cost_Amount) Total
from #table
group by DATEPART(year,[Date])
Define a range/grouping table.
Something similar to the following should work in most RDBMSs:
SELECT Grouping.id, SUM(Ingredient.ingredient_cost_amount) AS Ingredient_Cost_Amount,
SUM(Ingredient.cost_share_amount) AS Cost_Share_Amount
FROM (VALUES (2013, DATE('2013-01-01'), DATE('2014-01-01')),
(2012, DATE('2012-01-01'), DATE('2013-01-01'))) Grouping(id, gStart, gEnd)
JOIN Ingredient
ON Ingredient.date >= Grouping.gStart
AND Ingredient.date < Grouping.gEnd
GROUP BY Grouping.id
(DATE() and related conversion functions are heavily DB dependent. Some RDBMSs don't support using VALUES this way, although there are other ways to create the virtual grouping table)
See this blog post for why I used an exclusive upper bound for the range.
Using a range table this way will potentially allow the db to use indices to help with the aggregation. How much this helps depends on a bunch of other factors, like the specific RDBMS used.

SQL YTD for previous years and this year

Wondering if anyone can help with the code for this.
I want to query the data and get 2 entries, one for YTD previous year and one for this year YTD.
Only way I know how to do this is as 2 separate queries with where clauses.. I would prefer to not have to run the query twice.
One column called DatePeriod and populated with 2011 YTD and 2012YTD, would be even better if I could get it to do 2011YTD, 2012YTD, 2011Total, 2012Total... though guessing this is 4 queries.
Thanks
EDIT:
In response to help clear a few things up:
This is being coded in MS SQL.
The data looks like so: (very basic example)
Date | Call_Volume
1/1/2012 | 4
What I would like is to have the Call_Volume summed up, I have queries that group it by week, and others that do it by month. I could pull all the dailies in and do this in Excel but the table has millions of rows so always best to reduce the size of my output.
I currently group by Week/Month and Year and union all so its 1 output. But that means I have 3 queries accessing the same table, large pain, very slow not efficient and that is fine but now I also need a YTD so its either 1 more query or if I could find a way to add it to the yearly query that would ideal:
So
DatePeriod | Sum_Calls
2011 Total | 40
2011 YTD | 12
2012 Total | 45
2012 YTD | 15
Hope this makes any sense.
SQL is built to do operations on rows, not columns (you select columns, of course, but aggregate operations are all on rows).
The most standard approach to this is something like:
SELECT SUM(your_table.sales), YEAR(your_table.sale_date)
FROM your_table
GROUP BY YEAR(your_table.sale_date)
Now you'll get one row for each year on record, with no limit to how many years you can process. If you're already grouping by another field, that's fine; you'll then get one row for each year in each of those groups.
Your program can then iterate over the rows and organize/render them however you like.
If you absolutely, positively must have columns instead, you'll be stuck with something like this:
SELECT SUM(IF(YEAR(date) = 2011, sales, 0)) AS total_2011,
SUM(IF(YEAR(date) = 2012, total_2012, 0)) AS total_2012
FROM your_table
If you're building the query programmatically you can add as many of those column criteria as you need, but I wouldn't count on this running very efficiently.
(These examples are written with some MySQL-specific functions. Corresponding functions exist for other engines but the syntax would be a little different.)

SQL query question

I'm trying to do something in a query that I've never done before. it probably requires variables, but i've never done that, and I'm not sure that it does.
What I want is to get a list of sales, grouped first by affiliate, then by it's month.
I can do that, but here's the twist... I don't want the month, but month 1, month 2, month 3...
And those aren't Jan, feb, march, but the number of months since the day of first sale.
Is this possible in a query at all, or do I need to do this in my code.
Oh, mysql 5.1.something...
Sure, just write an expression in SQL that generates the number of months since the first sale (Do you mean the first sale for that afiliate? If so, you'll need a subquery)
And since you say you want a list of sales, I assume you don't really want to "Group By" affilaite and monthcount, you just want to Sort, or Order By those values)
If you wanted the Average sales amount, or the Count of sales, or some other Aggregate function of sales data, then you would be doing a "Group By"...
And I don't think you need to worry about sorting by the number of months, you can simply sort by the difference between each sales date and the rearliest sale date for each affiliate. (If you wanted to apply a third sorting rule, after the sales date sort, then you would need to be more careful.)
Select * From Sales S
Order By Affiliate,
SalesDate - (Select Min(SalesDate)
From Sales
Where Affiliate = S.Affiliate)
Or, if you really need it to be by the difference in months
Select * From Sales S
Order By Affiliate,
Month(SalesDate) -
(Select Month(Min(SalesDate))
From Sales
Where Affiliate = S.Affiliate)
This is possible in standard SQL if you use what I like to call "SQL gymnastics". It can be done with subqueries.
But it looks incredibly ugly, is hard to maintain and it's really not worth it. You're far better off using one of the many programming languages that wrap SQL (such as PL/SQL) or even a general purpose language that can call SQL (such as Python).
The result will be in two languages but will be all the more understandable than the same thing written in just SQL.