Selecting a table field and subtracting a CASE with a SUM function - sql

I'm writing a SQL Command for Crystal Reports and I'm still new to SQL, so I'm having trouble with the following scenario. I've got a SUM function to add up the costs of a production job to get me the actual costs. I want to formulate the margin from the invoice amount and subtract the actual cost from this SUM function to populate another field in my report. When the related invoice has a return applied, it shows as a credit memo type rather than a typical invoice. I want to add a CASE function to the Margin SQL statement.
I'm getting this CASE statement to work to get my actual costs:
,(CASE WHEN t1.[Type] = 'CM' THEN '0.00' ELSE (SELECT SUM(Act_Labor+Act_Material+Act_Service+Act_Labor_Burden+Act_Machine_Burden+Act_GA_Burden) FROM Job WHERE Top_Lvl_Job = t0.Job) END)as Act_Cost
I want to incorporate this CASE statement into my formula to get my Margin as seen below:
,(SELECT ISNULL(t0.Amount, 0) - SUM(Act_Labor+Act_Material+Act_Service+Act_Labor_Burden+Act_Machine_Burden+Act_GA_Burden) FROM Job WHERE Top_Lvl_Job = t0.Job) as Margin
I keep getting errors if I try to use the CASE statement in my Margin formula. I'm not sure where I'm going wrong with the sequence or if my syntax has multiple errors.
I've tried the following syntax, but keep getting errors:
,(SELECT ISNULL(t0.Amount,0) - (CASE WHEN t1.[Type] = 'CM' THEN '0.00' ELSE (SUM(Act_Labor+Act_Material+Act_Service+Act_Labor_Burden+Act_Machine_Burden+Act_GA_Burden) FROM Job WHERE Top_Lvl_Job = t0.Job) END))as Margin

So i figured out the answer to my problem. I changed the CASE statement to give me the information i need, but in a different way.
Rather than starting with the SELECT function to pull the invoice amount then use the CASE function, I changed the query to use the CASE function to populate the invoice amount since that was going to populate anyways based on my subtraction.
Here is the statement I'm using that is working now:
,(CASE WHEN t1.[Type] = 'CM' THEN ISNULL(t0.Amount, 0) ELSE (SELECT ISNULL(t0.Amount, 0) - SUM(Act_Labor+Act_Material+Act_Service+Act_Labor_Burden+Act_Machine_Burden+Act_GA_Burden) FROM Job WHERE Top_Lvl_Job = t0.Job)END) as Margin

Related

Alter a existing SQL statement, to give an additional column of data, but to not affect performance, so best approach

In this query, I want to add a new column, which gives the SUM of a.VolumetricCharge, but only where PremiseProviderBillings.BillingCategory = 'Water'. But i don't want to add it in the obvious place since that would limit the rows returned, I only want it to get the new column value
SELECT b.customerbillid,
-- Here i need SUM(a.VolumetricCharge) but where a.BillingCategory is equal to 'Water'
Sum(a.volumetriccharge) AS Volumetric,
Sum(a.fixedcharge) AS Fixed,
Sum(a.vat) AS VAT,
Sum(a.discount) + Sum(deferral) AS Discount,
Sum(Isnull(a.estimatedconsumption, 0)) AS Consumption,
Count_big(*) AS Records
FROM dbo.premiseproviderbillings AS a WITH (nolock)
LEFT JOIN dbo.premiseproviderbills AS b WITH (nolock)
ON a.premiseproviderbillid = b.premiseproviderbillid
-- Cannot add a where here since that would limit the results and change the output
GROUP BY b.customerbillid;
Bit of a tricky one, as what you're asking for will definitely affect performance (your asking SQL Server to do more work after all!).
However, we can add a column to your results which performs a conditional sum so that it does not affect the result of the other columns.
The answer lies in using a CASE expression!
Sum(
CASE
WHEN PremiseProviderBillings.BillingCategory = 'Water' THEN
a.volumetriccharge
ELSE
0
END
) AS WaterVolumetric

SQL TO MDX conversion (SUM and Case)

I'm having trouble with simple tasks on MDX since I'm new with it. I basically have a fact table with '1' and '0' on two of my columns. I want a new measure where I can get '1' or '0' if both measures = 1, and sum them to a total but I can't get through it.
This is my query, "BOTH" should be the result I want
select SUM(ASIGNACION_INICIAL), SUM(INICIADO),
SUM(CASE WHEN ASIGNACION_INICIAL = 1 AND INICIADO = 1 THEN 1 ELSE 0 END)
"BOTH",
ID_CAMARA
from EST_MAESTRA_CIVIL group by ID_CAMARA;
Your problem is more related to SSAS project design then MDX. In you SSAS project, go to dsv, there add a calulated column.In this column will implement your logic defined above. Now in your cube use this calculated column as a measure.

Is there an easier way than nested iifs to count mismatched conditions in SQL server

The picture below shows a table of accounts and the outcomes that I want to count. Ie every time the account number is 106844 and the outcome is "MESSAGE" or "ESCALATION EMAIL" that should count as 1 where any other outcome counts as 0. What I would normally do is a horrible mess of iifs like
sum( iif([account] = '106719' and [Outcome] in ('MESSAGE','ESCALATION_EMAIL'),1,iif([account] = '310827' and [outcome] <> 'ABORT' and 'CALL_OUTCOME_LB' in ("Call patched to Customer Care","Message Taken"),1,iif( ... , 0) as [Total Outcomes]
and so on but man it feel like there's got to be an easier way or one less prone to making a random mistake in the 7th nested iif and messing the whole thing up. Any ideas?
Don't use iif(). It is a function brought into SQL Server for back-compatibility to MS ACCESS. Why would you want to be backwards compatible to such a thing?
Use the ANSI standard CASE expression:
sum(case when account = '106719' and Outcome in ('MESSAGE', 'ESCALATION_EMAIL')
then 1
when account = '310827' and outcome <> 'ABORT' and
'CALL_OUTCOME_LB' in ("Call patched to Customer Care", "Message Taken")
then 1
. . .
else 0
end) as Total_Outcomes
I would also advise you to name your columns so they don't need to be escaped (why "Total Outcomes" became "Total_Outcomes"). That simplifies the code.
Why not use a lookup table that has the Account and Outcome and use that? Then, as requirements change, you could update the lookup table and not worry about your code.
Yeah... there is
The last parameter is for when the condition is false, everything else will fall in there.
SUM( IIF([ACCOUNT] = '106719' AND [OUTCOME] IN ('MESSAGE','ESCALATION_EMAIL'),1,0))

SQL: Calculate Percentage in new column using another column

I found it hard to describe what I wanted to do in the title, but I will be more specific here.
I have a reasonably long query:
SELECT
/*Amount earned with validation to remove outlying figures*/
Case When SUM(t2.[ActualSalesValue])>=0.01 OR SUM(t2.[ActualSalesValue])<0 Then SUM(t2.[ActualSalesValue]) ELSE 0 END AS 'Amount',
/*Profit earned (is already calculated then input into db, this just pulls that figure*/
SUM(t2.[Profit]) AS 'Profit',
/*Product Type - pulls the product type so that we can sort by product*/
t1.[ucIIProductType] AS 'Product Type',
/*Profit Percentage - This is to calculate the percentage of profit based on the sales price which uses 2 different columns - Case ensures that there are no wild values appearing in the reports as previously experienced*/
Case When SUM(t2.[ActualSalesValue])>=0.01 OR SUM(t2.[ActualSalesValue])<0 THEN (SUM(t2.[Profit])/SUM(t2.[ActualSalesValue])) ELSE 0 END AS 'Profit Percentage',
/*Percentage of Turnover*/
*SUM(t2.[ActualSalesValue])/(Select SUM(t2.[ActualSalesValue]) OVER() FROM [_bvSTTransactionsFull]) AS 'PoT'
/*The join is connect the product type with the profit and the amount*/
FROM [dbo].[StkItem] AS t1
INNER JOIN [dbo].[_bvSTTransactionsFull] AS t2
/*There attirbutes are the links between the tables*/
ON t1.[StockLink]=t2.[AccountLink]
WHERE t2.[TxDate] BETWEEN '1/Aug/2014' AND '31/Aug/2014' AND ISNUMERIC(t2.[Account]) = 1
Group By t1.[ucIIProductType]
The 'Percentage of Turnover' part I am having trouble with - I am trying to calculate the percentage of the Amount based on the total amount - using the same column. So eg: I want to take the Amount value in row 1, then divide it by the total amount of the entire column and then have that value listed in a new column. But I keep getting errors or I Keep getting 1 (because it wants to divide the value by the same value. CAN anyone please advise me on proper syntax for solving this:
/*Percentage of Turnover*/
*SUM(t2.[ActualSalesValue])/(Select SUM(t2.[ActualSalesValue]) OVER() FROM [_bvSTTransactionsFull]) AS 'PoT'
I think you want one of the following:
SUM(t2.[ActualSalesValue])/(Select SUM(t.[ActualSalesValue]) FROM [_bvSTTransactionsFull] t) AS PoT
or:
SUM(t2.[ActualSalesValue])/(SUM(SUM(t2.[ActualSalesValue])) OVER() ) AS PoT
Note: you should use single quotes only for string and date constants, not for column and table names. If you need to escape names, use square braces.

Showing specific data without filtering out query data

I need to build a form where one field (Unplanned Amount) will only populate with data if another field (status) equals a certain value ("not in workflow"). If the status equals anything else, Unplanned amount field would be blank.
The data is coming from three different tables:
Table 1) AccountNum
Table 2) DocNum, DocAmount, DocStatus
Table 3) CommitAmount
The value in CommitAmount will always equal DocAmount, but the value of DocAmount doesn't have to equal the value of the CommitAmount if it's "unplanned."
I tried putting the data into a query and using the following code on my form to no avail:
If Me.DocStatus = "Not in workflow" Then
Me.DocAmount = Null
Else
Me.DocAmount = [forms]![form2]![DocAmount]
End If
Does anyone know how to go about making a query-based form or report that allows what I've described above to take place? Or maybe this should not be done via a query?
Thanks!!
Put the IF statement into to data source for me.docamount
OR use a case statement in the query itself
select case docstatus when 'Not in workflow' then null else docamount end