I have a sql case statement that is working beautifully. I am trying to get the same thing to work in a Crystal report. The biggest issue is I need the report to add only the difference of two conditions, which I can't seem to make work in Crystal.
SQL:
select sum(case when type='PA' and tax_year=2022 then amt else 0 end) +
sum((case when type='UN' and tax_year in (0, 2022) then amt else 0 end) - (case when type='RA' then amt else 0 end)) -
sum(case when type='DR' and tax_year in (0,2022) then amt else 0 end) +
sum(case when type='CR' and tax_year=2022 then amt else 0 end) as total
From ar
where date_ between '7/1/2021' and '6/30/2022' and source='PT'
I have a year formula already in Crystal to total them in the appropriate year "buckets", so I am trying to get the types to work.
CRYSTAL:
If {AR.TYPE}='PA' then {AR.AMT}
else if {AR.TYPE}='DR' then -{AR.AMT}
else if {AR.TYPE}='CR' then {AR.AMT}
else if {AR.TYPE}='OP' then -{AR.AMT}
**else if {AR.TYPE}='UN' then ({AR.AMT} - if {AR.TYPE}='RA' then {AR.AMT})**
else {AR.AMT}
The bold piece above is giving me a difficult time.
I want the formula to add only the difference between all AR.TYPE='UN' and AR.TYPE='RA' but the Crystal formula I have above is just adding all UNs and ignoring the RAs
Use this logic:
If {AR.TYPE}='PA' then {AR.AMT}
else if {AR.TYPE}='DR' then -{AR.AMT}
else if {AR.TYPE}='CR' then {AR.AMT}
else if {AR.TYPE}='OP' then -{AR.AMT}
else if {AR.TYPE}='UN' then {AR.AMT}
else if {AR.TYPE}='RA' then -{AR.AMT}
else {AR.AMT}
Related
I am trying to calculate amortized costs from aws cost & usage reports (cur) for the billing period using the query mentioned in Well Architected Labs (https://wellarchitectedlabs.com/cost/300_labs/300_cur_queries/query_help/) but I am not getting the right numbers.
I can fetch the costs from cost explorer api directly but that won't match with cur data because cur is usually a day or two behind. How to get the exact amortized costs for the billing period using cur queries?
I am trying the following query that I got from the above mentioned link in well architected labs. This query is for account with have both ri & sp usage during billing period.
SELECT
DATE(lineitemusagestartdate) as month_line_item_usage_start_date,
SUM(CASE
WHEN (lineitemlineitemtype = 'SavingsPlanNegation') THEN 0
ELSE lineitemunblendedcost
END) AS sum_line_item_unblended_cost,
SUM(CASE
WHEN (lineitemlineitemtype = 'SavingsPlanCoveredUsage') THEN (safe_cast(savingsplansavingsplaneffectivecost as FLOAT64))
WHEN (lineitemlineitemtype = 'SavingsPlanRecurringFee') THEN (safe_cast(savingsplantotalcommitmenttodate as FLOAT64) - safe_cast(savingsplanusedcommitment as FLOAT64))
WHEN (lineitemlineitemtype = 'SavingsPlanNegation') THEN 0
WHEN (lineitemlineitemtype = 'SavingsPlanUpfrontFee') THEN 0
WHEN (lineitemlineitemtype = 'DiscountedUsage') THEN (safe_cast(reservationeffectivecost as FLOAT64))
WHEN (lineitemlineitemtype = 'RIFee') THEN (safe_cast(reservationunusedamortizedupfrontfeeforbillingperiod as FLOAT64) + CAST(reservationunusedrecurringfee as FLOAT64))
WHEN ((lineitemlineitemtype = 'Fee') AND (reservationreservationarn <> '')) THEN 0
ELSE lineitemunblendedcost
END) AS amortized_cost,
SUM(CASE
WHEN (lineitemlineitemtype = 'SavingsPlanRecurringFee') THEN (-(safe_cast(savingsplanamortizedupfrontcommitmentforbillingperiod as FLOAT64)))
WHEN (lineitemlineitemtype = 'RIFee') THEN (-(safe_cast(reservationamortizedupfrontfeeforbillingperiod as FLOAT64)))
WHEN (lineitemlineitemtype = 'SavingsPlanNegation') THEN (-(safe_cast(lineitemunblendedcost as FLOAT64)))
ELSE 0
END) AS ri_sp_trueup,
SUM(CASE
WHEN (lineitemlineitemtype = 'SavingsPlanUpfrontFee') THEN lineitemunblendedcost
WHEN ((lineitemlineitemtype = 'Fee') AND (reservationreservationarn <> '')) THEN lineitemunblendedcost
ELSE 0
END) AS ri_sp_upfront_fees
FROM TABLE_NAME
group by 1
order by 1 asc
I have a data source in tableau that looks something similar to this:
SKU Backup_Storage
A 5
A 1
B 2
B 3
C 1
D 0
I'd like to create a calculated field in tableau that performs a SUM calculation IF the SKU column contains the string 'A' or 'D' , and to perform an AVERAGE calculation if the SKU column contains the letters 'C' or 'B'
This is what I am doing:
IF CONTAINS(ATTR([SKU]),'A') or
CONTAINS(ATTR([SKU]),'D')
THEN SUM([Backup_Storage])
ELSEIF CONTAINS(ATTR([SKU]),'B') or
CONTAINS(ATTR([SKU]),'C')
THEN AVG([Backup_Storage])
END
UPDATE - desired output would be:
SKU BACKUP
A, D 6 (This is the SUM OF A and D)
B, C 2 (This is the AVG of B and C)
The calculation above shows as valid, however, I see NULLS in my data source table.
Any suggestion is appreciated.
I have named the calculated field:
SKU_FILTER_CALCULATION
Basically, IF THEN ELSE condition works when one test that is either TRUE/FALSE. Your specified condition is not a proper use case of IF THEN ELSE because SKUs can take all possible values. See it like this..
your data
SKU Backup_Storage
A 5
A 1
B 2
B 3
C 1
D 0
Let's name your calc field as CF, then CF will take value A in first row and will output SUM(5) = 5. For second row it will output sum(1) = 1, for third and onward rows it will output as avg(2) = 2, avg(3) = 3, avg(1) and sum(0) respectively. all these values just equals [Backup_storage] only and I'm sure that this you're not trying to get.
If instead you are trying to get sum(5,1,0) + avg(2,3,1) (obviously i have assumed + here) which equals 8 i.e. one single value for whole dataset, please proceed with this calculated field..
SUM(IF CONTAINS([SKU], 'A') OR CONTAINS([SKU], 'D')
THEN [Backup storage] END)
+
AVG(IF CONTAINS([SKU], 'B') OR CONTAINS([SKU], 'C')
THEN [Backup storage] END)
This will return an 8 when put to view
Needless to say, if you want any other operator instead of + you have to change that in CF accordingly
As per your edited post, I suggest a different methodology. Create diff groups where you want to perform different aggregations
Step-1 Create groups on SKU field. I have named this group as SKUG
Step-2 create a calculated field CF as
SUM(ZN(IF CONTAINS([SKU], 'A') OR CONTAINS([SKU], 'D')
THEN [Backup storage] END))
+
AVG(ZN(IF CONTAINS([SKU], 'B') OR CONTAINS([SKU], 'C')
THEN [Backup storage] END))
Step-3 get your desired view
Good Luck
I have a sql Statement with multiple cases now I have to write the statement in Dax
I tried using switch but the output is not same
the sql statement :
CASE WHEN #STRIKER!='' OR #NONSTRIKER!='' THEN (RUNS + (CASE WHEN BYES = 0 AND LEGBYES = 0 THEN OVERTHROW ELSE 0 END))
WHEN #BOWLER!='' THEN (RUNS + WIDE+ (CASE WHEN BALL.NOBALL > 0 AND (BALL.BYES > 0 OR BALL.LEGBYES > 0) THEN BALL.BYES + BALL.NOBALL + BALL.LEGBYES
WHEN BALL.NOBALL > 0 AND BALL.BYES = 0 AND BALL.LEGBYES = 0 THEN BALL.NOBALL
ELSE 0 END) + (CASE WHEN BYES = 0 AND LEGBYES = 0 THEN OVERTHROW ELSE 0 END))
ELSE GRANDTOTAL END ) AS RUNS
First, I would simplify the case statement,
I assume you have the case statements because NULLS can exist in your result? you could simply try
RUNS +
WIDE +
ISNULL(BALL.NOBALL,0) +
ISNULL(BALL.BYES,0) +
ISNULL(BALL.LEGBYES,0) +
ISNULL(OVERTHROW,0)
But if you've already got the model in PowerBI with those columns listed, you could simply add a calculated column that would sum all the columns which would ignore the nulls...
Total = RUNS + WIDE + NOBALL + BYES + LEGBYES + OVERTHROW
? but without the schema, its really hard to know what the solution might be.
good luck!
I am trying to rewrite SAS data step into SAS Sql. I keep getting syntax errors for the versions I have written so far. The documentation and examples do not address the type of if/then I am working with.
Below is the original data step:
data tmp1;
set _tst1;
if put(tin, $gp.) = 'N' and
(missing(npi_num) or index(npi_num,"~") >= 1) then del1=1;
if put(tin, $gp.) = "Y" or
put(tin, $msp.) = "Y" or
put(cats(tin, npi_num), $pio.) =: "Y" or
put(cats(tin, npi_num), $cpc.) = 'Y' then del2=1;
if sum(num_elig, msr_yes, num_excl, msr_no) ^gt 0 then del3=1;
if sum(del1,del2,del3) > 0 then delete;
run;
Here is my attempt:
proc sql;
create table tst as
select *,
case
when
put(tin, $gp.) = 'N' and
(missing(npi_num) or index(npi_num,"~") >= 1)
then 1
else 0
end as del1
when
put(tin, $gp.) = "Y" or
put(tin, $msp.) = "Y" or
put(cats(tin, npi_num), $pio.) =: "Y" or
put(cats(tin, npi_num), $cpc.) = 'Y'
then 1
else 0
end as del2
when
sum(num_eligible, msr_met, num_exclusion, msr_not_met) ^gt 0
then 1
else 0
end as del3
from _tst1;
quit;
I am new to SML and I have write a program that takes two years and compares them, then takes two months and compares them, and finally two dates.
The problem im having is that if the year is older than the first it should stop and false, but some how not sure if it is my logic or something it continues to check the months and then the dates before returning true or false.
I want it only check the month if the year is false and only check the day if the month is false.
fun is_older(year1 : int, month1 : int, day1 : int, year2 : int, month2 : int, day2 : int) =
if year1 < year2 andalso year1 > 0
then true
else
if month1 < month2 andalso month1 > 0 andalso month2 <= 12
then true
else
if day1 < day2 andalso day1 > 0 andalso day2 <= 31
then true
else false;
I'm assuming you're trying to compare two dates in a year, and return true/false value. What you did is mostly correct. In your second if statement, you want to check if month1<month2 only if year1=year2. Otherwise,even if year1=2014, and year2=2013, you'll get true value if their month agree with your second if statement.
Similarly, in your third if statement, you want to check days only if year1=year2 andalso month1=month2.