Mysql query issue with if statements in select - mysql

Trying to get this query to work. I'm having issues with brackets I think.
SELECT (fielda - fieldb - (
IF ((cola <= 5),
1,
IF ((cola >= 6 AND cola <= 12),
2,
IF ((cola >= 13 AND cola <= 20),
3,
IF ((cola >= 21 AND cola <= 28), 4)
)
)
) ))
AS result FROM the table r WHERE r.fieldx = 3148 AND cola <= 18 ORDER BY result LIMIT 1
Mysql returns:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')))) ) AS result FROM

The last IF does not have an else argument. While one might expect MySQL to understand this anyhow, it doesn't appear to be valid syntax according to http://dev.mysql.com/doc/refman/5.0/en/control-flow-functions.html#function_if

If I had to guess (and going by the information you've provided) I would say the last IF() is missing an else condition which is making the math function fail.
IF ((cola >= 21 AND cola <= 28), 4, ???)
Populate the question marks with an "all else fails"/"default" value and you should be safe. However, I believe mysql (assuming it's a non-nullable field) will use the default value for the type/column if you specify NULL as the else condition (but I may be wrong).

Related

Sum two columns in SQL where one columns needs to be negated

I would like to sum two columns in SQL and if the sum is greater than 0, then output it to one of the columns and if it is lesser than 0, then output to another column.
My code looks like this:
SELECT IF(SUM(`processed_quantity_long`,-1*`processed_quantity_short`) > 0,SUM(`processed_quantity_long`,-1*`processed_quantity_short`) AS `Position Long`,SUM(`processed_quantity_long`,-1*`processed_quantity_short`) AS `Position Short`)
From table A
GROUPBY date
It is returning me this error:
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '-1*processed_quantity_short)>0,SUM(processed_quantity_long,-1*`processed_qua' at line 5
Not sure how to resolve this error.
SUM does not take two arguments. Just subtract the two numbers before calculating the sum:
SELECT
CASE WHEN SUM(processed_quantity_long - processed_quantity_short) >= 0 THEN SUM(processed_quantity_long - processed_quantity_short) END AS `Position Long`,
CASE WHEN SUM(processed_quantity_long - processed_quantity_short) < 0 THEN SUM(processed_quantity_long - processed_quantity_short) END AS `Position Short`
FROM tablea
GROUP BY date
you did wrong on inside if
SELECT IF(
SUM(processed_quantity_long-processed_quantity_short) > 0,
SUM(`processed_quantity_long`-`processed_quantity_short`) ,
SUM(`processed_quantity_long`-`processed_quantity_short`) AS `Position Short`
) From tableA GROUP BY date
general if statement is like below
SELECT IF(500<1000, "YES", "NO")
Or use case when
case when SUM(`processed_quantity_long`-`processed_quantity_short`) > 0
then SUM(`processed_quantity_long`-`processed_quantity_short`)
else SUM(`processed_quantity_long`-`processed_quantity_short`) as position
from tableA GROUP BY date
Perhaps the simplest way to write the code is:
SELECT GREATEST(SUM(processed_quantity_long - processed_quantity_short), 0) AS Position_Long,
LEAST(SUM(processed_quantity_long - processed_quantity_short), 0) AS Position_Short
FROM tablea
GROUP BY date

MySQL Where clause same key twice for two separate values

I am generating the following query
SELECT * FROM Report WHERE submittedOn >= :minDateFilter
AND submittedOn <= :maxDateFilter AND non_issue = 1 AND
non_issue = 0 ORDER BY submitted
However, I'm not getting anything returned (it works fine if I omit: AND non_issue = 1 AND
non_issue = 0, or omit just one of these, but nothing is being returned when both of these clauses are present.
Ideally I'd like to keep the statement how it is, as it's generated on the fly and I'd like to be able to display both types of report from the same query.
I feel like my syntax might be incorrect, but it's not throwing any errors, any suggestions?
non_issue can not have 2 values at same time on a given row. I think you would like to use OR:
SELECT * FROM Report WHERE submittedOn >= :minDateFilter
AND submittedOn <= :maxDateFilter AND (non_issue = 1 OR
non_issue = 0) ORDER BY submitted
You can use the IN instead of non_issue = 1 AND non_issue = 0 condition.
The same entry can't be non_issue equal to 0 and 1 same time.
SELECT *
FROM Report
WHERE submittedOn >= :minDateFilter AND
submittedOn <= :maxDateFilter AND
non_issue IN (0, 1)
ORDER BY submitted

Sql Server 2008 coalesce

The following sql returns correct data formatted just as needed, except when no data is returned.
Desired result -- using the coalesce on ename--
is to return 'none' when no data is returned.
What is it I am doing wrong on the coalesce? Why does it not return 'none' when no data is returned?
When no data is returned, we get all the column names and all are null.
all pointers and suggestions appreciated.
select
ltrim(right(convert(varchar(20), tstart, 100), 7))
as 'START TIME',
ltrim(right(convert(varchar(20), tend, 100), 7))
as 'END TIME',
coalesce(vb.tname, 'none') as TITLE,
tr.description as LOCATION
from vwbooks vb
join troom tr
on vb.room = tr.id
where vb.room in(select id
from tblroom
where building = 4971
and vb.tstart >= floor(cast(getdate() as float))
and vb.tstart < ceiling(cast(getdate() as float))
and datepart(hour, vb.tstart) between 6 and 18
You are returning 0 rows. You are interpreting these as null. You need to understand why nothing is returned. The coalesce will work when it gets a row!

Trying to fetch COUNT() on weekday and weekend

I have a table that contains a column (created) that stores a unix timestamp when that item has been created.
Now I want to COUNT() all items that have been created on a weekday (Monday to Friday), compared to all items that have been created on the weekened (Saturday and Sunday).
My query is:
SELECT
IF (WEEKDAY(FROM_UNIXTIME(`created`)) >= 0 AND WEEKDAY(FROM_UNIXTIME(`created`)) >= 4) THEN COUNT(*) AS `weekday`,
IF (WEEKDAY(FROM_UNIXTIME(`created`)) <= 5) THEN COUNT(*) AS `weekend`
FROM `mytable`
But the error I get is
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') THEN COUNT(*), IF (WEEKDAY(FROM_UNIXTIME(created)) <= 5) THEN COUNT(*)' at line 3
Any help is highly appreciated.
You do not appear to be using the correct syntax. http://dev.mysql.com/doc/refman/5.1/en/control-flow-functions.html#function_if
Quoted from the above url,
IF(expr1,expr2,expr3)
If expr1 is TRUE (expr1 <> 0 and expr1 <> NULL) then IF() returns expr2; otherwise it returns expr3. IF() returns a numeric or string value, depending on the context in which it is used.".
I believe this would be the correct form for your query,
SELECT
DATE(FROM_UNIXTIME(`created`)) AS `date`,
IF (WEEKDAY(FROM_UNIXTIME(`created`)) >= 0 AND WEEKDAY(FROM_UNIXTIME(`created`)) <= 4, COUNT(*), 0), --WeekDay Count
IF (WEEKDAY(FROM_UNIXTIME(`created`)) >= 5 AND WEEKDAY(FROM_UNIXTIME(`created`)) <= 6, COUNT(*), 0) --Weekend Count
FROM mytable
I have found this link as well to the weekday function. Which leads me to believe your ranges were not correct to begin with.
http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_weekday

How to have a range in a MySQL If statement?

I'm trying to make a select that calculates affiliate payouts.
my approach is pretty simple.
SELECT
month(payments.timestmap)
,sum(if(payments.amount>=29.95,4,0)) As Tier4
,sum(if(payments.amount>=24.95<=29.94,3,0)) As Tier3
,sum(if(payments.amount>=19.95<=24.94,2,0)) As Tier2
FROM payments
GROUP BY month(payments.timestamp)
The above does not work because MySQL is not evaluating the second part of the condition. Btw it does not cause a syntax error and the select will return results.
Before the above I tried what I was assuming would work like "amount between 24.94 AND 29.94" this caused an error. so then I tried "amount >= 24.94 AND <= 29.94"
So is it possible to have a range comparison using IF in MySql?
The second part of the expression evaluates when you use AND -
SELECT
month(payments.timestmap)
,sum(if(payments.amount>=29.95,4,0)) As Tier4
,sum(if(payments.amount>=24.95 AND payments.amount<=29.94,3,0)) As Tier3
,sum(if(payments.amount>=19.95 AND payments.amount<=24.94,2,0)) As Tier2
FROM payments
GROUP BY month(payments.timestamp)
I'm not entirely sure why the between clause didn't work for you, but the above should do the job.
There is always the BETWEEN...AND... operator in MySQL.
What error did your first attempt give you? It should definitely work. However, note that the second form you have is incorrect syntax. It should be amount >= 24.94 and amount <= 29.94.
SELECT
month( payments.timestamp )
,sum( if( payments.amount >= 29.95, 4, 0 ) ) As Tier4
,sum( if( payments.amount BETWEEN 24.95 AND 29.94, 3, 0 ) ) As Tier3
,sum( if( payments.amount BETWEEN 19.95 AND 24.94, 2, 0 ) ) As Tier2
FROM payments
GROUP BY month( payments.timestamp )
This should work also, I tested both with BETWEEN and with > < to make sure they worked the same in one of my queries. So yes, both work.