Conditional where in SQL based on Value? - mysql

I am doing a report whereby I can't construct the SQL programatically. I have two values that are fed into the report. The values that can be one of the following three options:
redeem
purchase
redeem AND purchase
The query needs to have a WHERE clause. If "redeem" is fed in, it must have:
... WHERE balance < 0
If "purchase" is fed in, it must have:
... WHERE balance >= 0
if both are fed in, this condition can be left out completely, or it can be said:
... WHERE balance >= 0 OR balance < 0 --> but this is redundant
Is there a way to apply this kind of logic in SQL? Is something like this possible in SQL:
SELECT * FROM account WHERE (if param1 = 'redeem' then 'balance <= 0) ... etc
?

Yep. You're almost there.
WHERE (param='redeem' and balance <=0) or (param='purchase' and balance>=0) or (param='redeem AND purchase ')

Use CASE statements in your WHERE clause. You can find examples here.
I tried the following code in MySQL and it works:
SET #param = 'purchase';
SELECT * FROM TEST.ACCOUNT
WHERE CASE
WHEN #param = 'redeem' THEN BALANCE < 0
WHEN #param = 'purchase' THEN BALANCE >= 0
ELSE TRUE
END;

Would this do the trick?
WHERE
(purchase is not null && balance >= 0)
OR
(redeem is not null && balance < 0)

CASE WHEN param1 = 'redeem' THEN balance <= 0

Related

Add a not empty check for a date field into a query

Is there a way to alter this query so that it would check if frp_fundraisingprogram.start_date is not empty or contains the default value?
SELECT frp_fundraisingprogram.id AS id
FROM frp_fundraisingprogram
WHERE frp_fundraisingprogram.start_date <= DATE_ADD(UTC_TIMESTAMP(), INTERVAL - 2 day)
AND frp_fundraisingprogram.date_entered > '2015-04-09 16:55:18'
AND NOT EXISTS
(SELECT * FROM aow_processed
WHERE aow_processed.aow_workflow_id='9bc1bb2e-cd5a-5c75-cc68-5526ae30331e'
AND aow_processed.parent_id=frp_fundraisingprogram.id
AND aow_processed.status = 'Complete' AND aow_processed.deleted = 0)
AND frp_fundraisingprogram.deleted = 0
Just include that in your where clause...
`...WHERE not isnull(frp_fundraisingprogram.start_date)
AND frp_fundraisingprogram.start_date != '0000-00-00 ...`
That is if you are trying to exclude these records. You can reverse the logic if you only want these records to show up.

IF Then Else Mysql

Working on a view that pulls from two table however in one table I need to select either one field or another depending on a third..it's the if else that has me stubbed.
Create view as
select
pens.PartNo,
pens.Title,
ranges.weight
if(pens.SpeacialOffer = 1 then pens.offer as Price else pens.Price)
from
pens, ranges
where
pens.penrange = ranges.id;
If the specialoffer is falged the the view needs to pull in the offer else it needs to pull in the Price.
What you need is a CASE operator:
CASE
WHEN condition
THEN value_a
ELSE value_b
END
So in your case:
CASE
WHEN pens.SpeacialOffer = 1
THEN pens.offer
ELSE pens.price
END
This replaces the entire column definition in your SELECT statement, so the whole view becomes:
Create View as
Select
pens.PartNo,
pens.Title,
ranges.weight,
Case
When pens.SpeacialOffer = 1
Then pens.offer
Else pens.price
End as Price
From
pens, ranges
Where
pens.penrange = ranges.id;
Use CASE, also converted the query to explicit join instead of implicit join
select pens.PartNo,
pens.Title,
ranges.weight,
(Case when
pens.SpeacialOffer = 1 then
pens.offer else pens.Price
end ) as Price
FROM pens,
JOIn ranges
ON pens.penrange = ranges.id;
Here's one way:
Create view as select
pens.PartNo,
pens.Title,
ranges.weight,
(pens.SpeacialOffer * pens.offer + (1 - pens.SpeacialOffer) * pens.price) as Price
from
pens,
ranges
where
pens.penrange = ranges.id;

mysql / case / when / then

Can you help me please.
Where I have error in the following mysql query?
SELECT *,
CASE
WHEN vat = '1' THEN '1.10'
WHEN vat = '2' THEN '1.21'
END AS _vat,
CASE
WHEN sleva_kc != '' AND sleva_procent = '' THEN ((cena - sleva_kc) * _vat)
WHEN sleva_kc = '' AND sleva_procent != '' THEN ((cena * (1 - (sleva_procent / 100))) * _vat)
WHEN sleva_kc = '' AND sleva_procent = '' THEN (cena * _vat) END AS _cena
FROM kws_produkty WHERE _cena >= '100' AND _cena <= '500'
I use mysql connector:
#mysql_connect(HOST, USER, PASS)
explanation:
vat = VAT
cena = price
sleva_kc = Amount of discount in cash
sleva_procent = Amount of discount in percent
I need get output:
_cena = price with DISCOUNT and VAT (DISCOUNT can be a percentage or amount, VAT can be higher or smaller)
Thank you.
Your SQL is COMPLETELY mangled. You have your case statements in a place where they cannot be used and you are using elseif but do have have an if statement going.
SELECT
CASE .... END CASE,
IF ... THEN ... ELSEIF ... END IF
FROM yourtable
WHERE ....
I suggest you start reading the syntax documentation: https://dev.mysql.com/doc/refman/5.0/en/case.html
Your CASE WHEN ... END expressions should be part of the field list - before your FROM-clause.
The use of a column alias name in the WHERE-clause is illegal, see manual:
Standard SQL disallows references to column aliases in a WHERE clause. This restriction is imposed because when the WHERE clause is evaluated, the column value may not yet have been determined.

Calculate Percent Difference in SQL Server

I have two months with two values, for example:
July-2013 1838.08
Aug-2013 3500.08
How can I calculate the percentage difference in August compared with July?
The formula for this is easy it's (Curr-Prev)*100.0/Prev, what's not clear is how to apply it since we do not know your table definition, contents or keys, and thus do not know how to generically select one month and it's previous value. But, hard-coding it would be like this:
SELECT
100.0*(curr.Val - prev.Val) / prev.Val As PercentDiff
FROM yourTable As curr
JOIN yourTable As prev
ON curr.MonthStr = 'Aug-2013' AND prev.MonthStr = 'July-2013'
The problem with working out percentage changes is that you need to be careful of when the 'old value' is 0 or you will get an error.
One approach is using nullif(old_Value, 0) but then the problem with that is when old values are 0 you are asking for New_Value/NULL which is the new value. (definitely not the % change)
I worked around it like this:
(case
when
OldValue = 0 and NewValue = 0
then
cast(0 as Decimal(10,2))
when
OldValue = 0
then
'Na'
else
cast(cast(
(
(
(cast(NewValue as decimal(11,3)) -
cast(OldValue as decimal(11,3))
)*100
)/cast(OldValue as decimal(11,3))
) as decimal(20,3)
) as varchar
)
end) '% Change'
I probably threw a lot more casts than necessary but it works well for me. Gives Na when necessary and 0 when necessary.
SELECT VAR(Bonus) 'Variance',
STDEVP(Bonus) 'Standard Deviation',
STDEV(Bonus) 'Standard Deviation',
VARP(Bonus) 'Variance for the Population'
FROM Sales.SalesPerson;
giving credit to fololwing post
http://blog.sqlauthority.com/2008/01/20/sql-server-introduction-to-statistical-functions-var-stdevp-stdev-varp/
to handle zeroes in the denominator, i use:
case
when oldVal<>0 then ((newVal-oldVal)*100.0)/oldVal
else
case when newVal=0 then 0 else Null end
end
this will return 0 if newVal and oldVal are both 0, and Null if oldVal is zero but newVal is non-zero.
multiplying by 100.0 (as opposed to 100) will implicitly convert int fields into decimal. i find it cleaner than try_convert().

MySQL IF ELSEIF in select query

I'm trying to select different prices of a product based on the quantity that user chooses.
This is the query I'm working on (it has a syntax error):
select id,
(SELECT
IF(qty_1<='23',price,1)
ELSEIF(('23'>qty_1 && qty_2<='23'),price_2,1)
ELSEIF(('23'>qty_2 && qty_3<='23'),price_3,1)
ELSEIF('23'>qty_3,price_4,1)
END IF) as total
from product;
You have what you have used in stored procedures like this for reference, but they are not intended to be used as you have now. You can use IF as shown by duskwuff. But a Case statement is better for eyes. Like this:
select id,
(
CASE
WHEN qty_1 <= '23' THEN price
WHEN '23' > qty_1 && qty_2 <= '23' THEN price_2
WHEN '23' > qty_2 && qty_3 <= '23' THEN price_3
WHEN '23' > qty_3 THEN price_4
ELSE 1
END) AS total
from product;
This looks cleaner. I suppose you do not require the inner SELECT anyway..
IF() in MySQL is a ternary function, not a control structure -- if the condition in the first argument is true, it returns the second argument; otherwise, it returns the third argument. There is no corresponding ELSEIF() function or END IF keyword.
The closest equivalent to what you've got would be something like:
IF(qty_1<='23', price,
IF('23'>qty_1 && qty_2<='23', price_2,
IF('23'>qty_2 && qty_3<='23', price_3,
IF('23'>qty_3, price_4, 1)
)
)
)
The conditions don't all make sense to me (it looks as though some of them may be inadvertently reversed?), but without knowing what exactly you're trying to accomplish, it's hard for me to fix that.
I found a bug in MySQL 5.1.72 when using the nested if() functions .... the value of column variables (e.g. qty_1) is blank inside the second if(), rendering it useless. Use the following construct instead:
case
when qty_1<='23' then price
when '23'>qty_1 && qty_2<='23' then price_2
when '23'>qty_2 && qty_3<='23' then price_3
when '23'>qty_3 then price_4
else 1
end
For your question :
SELECT id,
IF(qty_1 <= '23', price,
IF(('23' > qty_1 && qty_2 <= '23'), price_2,
IF(('23' > qty_2 && qty_3 <= '23'), price_3,
IF(('23' > qty_2 && qty_3<='23'), price_3,
IF('23' > qty_3, price_4, 1))))) as total
FROM product;
You can use the if - else control structure or the IF function in MySQL.
Reference:
http://easysolutionweb.com/sql-pl-sql/how-to-use-if-and-else-in-mysql/
As per Nawfal's answer, IF statements need to be in a procedure. I found this post that shows a brilliant example of using your script in a procedure while still developing and testing. Basically, you create, call then drop the procedure:
https://gist.github.com/jeremyjarrell/6083251