Converting Access SQL to T-SQL - sql-server-2012

I have a created field in an Access database that I am trying to re-create in T-SQL. I am getting some incorrect results and I think it is how I wrote the code. Here is the field in Access that is working correctly:
MCP Actual: IIf([lever]="MCP",[actual usd]*IIf([split flag]="x",[split percent],1))*[Allocation Value]
Here is how I have it coded in SQL:
MCPActual =
CASE
WHEN pbd.Lever = 'MCP' THEN pbd.ActualUSD * CASE WHEN ou.SplitFlag = 'x' THEN ((pbd.ActualUSD * ou.SplitPercent) * pda.AllocationValue) END
ELSE ((pbd.ActualUSD * 1) * pda.AllocationValue)
END

I think you haven't got the END and brackets in the correct sequence try
CASE
WHEN pbd.Lever = 'MCP' THEN pbd.ActualUSD *
(CASE WHEN ou.SplitFlag = 'x' THEN
(pbd.ActualUSD * ou.SplitPercent * pda.AllocationValue )
ELSE
(pbd.ActualUSD * pda.AllocationValue) END)
END
You don't need to multiply by 1 unless you are trying to covert a negative / positive value.

Related

Case expression with Boolean from PostgreSQL to SQL Server

I am translating a query from PostgreSQL to SQL Server. I didn't write the query in PostgreSQL and it's quite complicated for my knowledge so i don't understand every piece of it.
From my understand: we are trying to find the max version from p_policy and when insurancestatus = 7 or 14 / transactiontype = CAN, we compare two dates (whose format are BIG INT).
This is the PG Query:
SELECT *
FROM BLABLABLA
WHERE
pol.vnumber = (
SELECT MAX(pol1.vnumber)
FROM p_policy pol1
AND ( CASE WHEN pol1.insurancestatus IN (7,14)
or pol1.transactiontype IN ('CAN')
-- ('CAN','RCA')
THEN pol1.veffectivedate = pol1.vexpirydate
ELSE pol1.veffectivedate <> pol1.vexpirydate
END
)
AND pol1.vrecordstatus NOT IN (30,254)
etc.
I am used to have a where statement where I compare it to a value. I understand here from the Case statement we will have a boolean, but still that must be compared to something?
Anyway the main purpose is to make it work in SQL, but I believe SQL can't read a CASE statement where THEN is a comparison.
This is what I tried:
SELECT *
FROM BLABLABLA
WHERE pol.vnumber =
(
SELECT MAX(pol1.vnumber)
FROM p_policy pol1
WHERE sbuid = 4019
AND ( CASE WHEN pol1.insurancestatus IN (7,14)
or pol1.transactiontype IN ('CAN')
THEN CASE
WHEN pol1.veffectivedate = pol1.vexpirydate THEN 1
WHEN pol1.veffectivedate <> pol1.vexpirydate THEN 0
END
END
)
AND pol1.vrecordstatus NOT IN (30,254)
etc.
And then I get this error from SQL Server (which directly the last line of the current code - so after the double case statement)
Msg 4145, Level 15, State 1, Line 55
An expression of non-boolean type specified in a context where a condition is expected, near 'AND'.
Thank you !Let me know if it is not clear
I think you want boolean logic. The CASE expression would translate as:
(
(
(pol1.insurancestatus IN (7,14) OR pol1.transactiontype = 'CAN')
AND pol1.veffectivedate = pol1.vexpirydate
) OR (
NOT (pol1.insurancestatus IN (7,14) OR pol1.transactiontype = 'CAN')
AND pol1.veffectivedate <> pol1.vexpirydate
)
)
There are 2 main issues with your snippet, SQL Server-syntax-wise.
SELECT * FROM BLABLABLA WHERE
pol.vnumber = /* PROBLEM 1: we haven't defined pol yet; SQL Server has no idea what pol.vnumber is here, so you're going to get an error when you resolve your boolean issue */
(
SELECT MAX(pol1.vnumber)
FROM p_policy pol1
WHERE sbuid = 4019
AND ( CASE WHEN pol1.insurancestatus IN (7,14)
or pol1.transactiontype IN ('CAN')
THEN CASE
WHEN pol1.veffectivedate = pol1.vexpirydate THEN 1
WHEN pol1.veffectivedate <> pol1.vexpirydate THEN 0
END
END
) /* PROBLEM 2: Your case statement returns a 1 or a 0..
which means your WHERE is saying
WHERE sbuid = 4019
AND (1)
AND pol1.vrecordstatus NOT IN (30,254)
SQL Doesn't like that. I think you meant to add a boolean operation using your 1 or 0 after the parenthesis.
like this: */
= 1
AND pol1.vrecordstatus NOT IN (30,254)

Nested case conditionals in PostgreSQL, syntax error?

I use PostgreSQL and I would like to combine these two case conditions, but when I uncomment the code, I get a syntax error. This is not a difficult instruction. I want to divide or multiply the obtained number depending on the condition. How can I enter it so that the code is compiled?
SELECT
SUM(
CASE
WHEN transactions.recipient_account_bill_id = recipientBill.id AND recipientBill.user_id = 2
THEN 1
ELSE -1
END * transactions.amount_money
/* CASE
WHEN senderBillCurrency.id = recipientBillCurrency.id
THEN NULL
ELSE
CASE
WHEN recipientBillCurrency.base = true
THEN /
ELSE *
END senderBillCurrency.current_exchange_rate
END */
) as TOTAL
FROM transactions
LEFT JOIN bills AS senderBill ON senderBill.id = transactions.sender_account_bill_id
LEFT JOIN bills AS recipientBill ON recipientBill.id = transactions.recipient_account_bill_id
LEFT JOIN currency as senderBillCurrency ON senderBillCurrency.id = senderBill.currency_id
LEFT JOIN currency as recipientBillCurrency ON recipientBillCurrency.id = recipientBill.currency_id
WHERE 2 IN (senderBill.id, recipientBill.id)
You cannot create dynamic SQL expressions like that. A CASE expression cannot return an operator as if SQL was some sort of macro language. You can only return an expression.
You already used the following approach using 1 and -1 with your multiplication. Why not also use it with N and 1/N:
<some expression> * CASE WHEN condition THEN 1 / N ELSE N END
Or in your case:
<some expression> * CASE
WHEN senderBillCurrency.id = recipientBillCurrency.id THEN 1
WHEN recipientBillCurrency.base THEN 1 / senderBillCurrency.current_exchange_rate
ELSE senderBillCurrency.current_exchange_rate
END
Notice, you can put several WHEN clauses in a CASE expression. No need to nest them

calculated field using if and or in ms-sql

IF(
[dbo.tblx.Category] = 'WS' OR [dbo.tblx.Category] = 'SEM',
0,
[dbo.tblx.Tonnes] * [dbo.tblx.Grade] / 1000
)
this returns the entire text and not the "calculation"
can someone help me...what am I doing wrong?
i tried
CASE WHEN dbo.tblx.Category = 'WS' OR dbo.tblx.Category = 'SEM' THEN 0
ELSE dbo.tblx.Tonnes * dbo.tblx.Grade / 1000
END AS Metal
Do perhaps insert something before "CASE WHEN"? it is not running
As I understood, you are trying to create a computed column, using value from other table.
I think in this case you have to use a User Defined function in the formula for computed column. If you give more information I can try to write some code for you.
Instead, if you just want to add a column in a query you can use:
CASE WHEN dbo.tblx.Category = 'WS' OR dbo.tblPTx.Category = 'SEM' THEN 0
ELSE dbo.tblx.Tonnes * dbo.tblx.Grade / 1000 END AS NAME_OF_YOUR_NEW_COLUMN
Update
DECLARE #myvar INT;
SET #myvar = CASE WHEN ([dbo.tblx.Category] = WS OR [dbo.tblPTx.Category] = SEM) THEN 0
ELSE [dbo.tblx.Tonnes] * [dbo.tblx.Grade] / 1000
END

How to use case when in SQL Server 2008

I want to use case after where clause in SQL Server 2008; how can I use it like
select *
from MPR
where
case when #min >= 0
then MainComponent_Id = #mainc and SubComponent_Id = #subcomp
else MainComponent_Id = #mainc and SubComponent_Id = #subcomp and MinorComponent_Id = #minorc
end
end
I am using a stored procedure, and in my stored procedure if minorcomponent_id value is 0 then it will add 1 one else 2 one will work.
I had tried hard but its giving error in near case.
How to resolve it?
Thanks
You don't need to use a CASE statement. You can simplify logic as follows:
select
*
from
MPR
where
MainComponent_Id = #mainc AND SubComponent_Id = #subcomp
AND (#min >= 0 OR MinorComponent_Id = #minorc)

How can I structure an IF statement inside of a SELECT statement?

I'm hoping that what I have paints a clear enough picture of what I am trying to accomplish:
SELECT [Date]
,[ChargeCode]
,[ChargeDescription]
,[HHY_Qty]
,[PatPrice]
, IF ISNUMERIC(HHY_Qty) AND ISNUMERIC(PatPrice)
BEGIN
CAST(HHY_Qty AS INT) * CAST(PatPrice AS INT) AS ExtAmt
END
ELSE
0 AS ExtAmt
END
FROM [dbo].[ChargeDetails]
WHERE PatientNumber = '1271'
HHY_Qty and PatPrice are both VARCHAR types in a MSSQL database. They were created with a BULK INSERT from a very very very dirty CSV from an AS400 export. Here, I am trying to do some multiplication IF the fields are numeric values, otherwise ExtAmt should be 0. Is that possible? If not,, is there a workaround?
Use a CASE statement:
CASE WHEN ISNUMERIC(HHY_Qty) = 1 AND ISNUMERIC(PatPrice) = 1 THEN CAST(HHY_Qty AS INT) * CAST(PatPrice AS INT) ELSE 0 END AS ExtAmt