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

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

Related

MySQL query to return 1 and 0 based on difference between dates

In MySQL Database I have a table ABC that consists of a column 'LastDate'.
LastDate which has datatype as DATETIME. The default value for this 'NULL'
I need to write a query for the table which would
Return '1' in these cases.
1) If DATEDIFF(CURRENT_TIME,LastDate) is >15 or if DATEDIFF(CURRENT_TIME,LastDate) is
NULL(i.e defaultVal).
return '0' if DATEDIFF(CURRENT_TIME,LastDate) is <15.
I tried to write an SQL query for this but was unable to do it. Please help me write this Query. Thanks in advance.
You can be explicit about your logic:
select t.*,
(case when DATEDIFF(CURRENT_TIME, LastDate) > 15 or
LastDate is null
then 1 else 0
end) as flag
from t;
This can be simplified to:
select t.*,
coalesce(DATEDIFF(CURRENT_TIME, LastDate) <= 15, 1) as flag
from t;

Count two columns from 1 table

I got this table (date, indoor_km, outdoor_km,...)
I have found the SQL count to count indoor_km or outdoor_km
but I'm looking for a SQL count for the 2 columns from 1 table.
You can use the SUM function over a condition in order to count entries that satisfy your condition of IS NOT NULL:
select
sum( case when indoor_km is not null then 1 else 0 end ) As indoorKmCount,
sum( case when outdoor_km is not null then 1 else 0 end ) As outdoorKmCount
from table
You simply add them
SELECT SUM(indoor_km) + SUM(outdoor_km)
FROM...
To select the sum only for a time period simply add a WHERE clause, either using BETWEEN or >=, <=, I used the latter in my example
SELECT SUM(indoor_km) + SUM(outdoor_km)
FROM Fietsen_2018
WHERE datum >= '1/01/2018' AND datum <='31/01/2018'

How do I aggregate with group by in mysql withou setting sql mode?

This query gets the output I want. In order to run it I have to run
SET sql_mode = '';
Because otherwise I get an error:
SELECT list is not in GROUP BY clause and contains nonaggregated column 'knownLoss.t1.loss' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
SELECT
t1.klDate AS LDate
, t1.Category
, t1.reason AS Reason
, sum(t1.loss) AS Loss
, round(t1.loss / t2.loss,2) AS Percentage
FROM
deptkl t1
JOIN (
SELECT
Store
, sum(loss) AS loss
FROM
deptkl
WHERE
klDate >= date_sub(SUBDATE(curdate(), WEEKDAY(curdate())), interval 7 day)
AND
klDate < SUBDATE(curdate(), WEEKDAY(curdate()))
AND
Store = 19
AND
Department = 80
) t2 ON t1.Store = t2.Store
WHERE
klDate >= date_sub(SUBDATE(curdate(), WEEKDAY(curdate())), interval 7 day)
AND
klDate < SUBDATE(curdate(), WEEKDAY(curdate()))
AND
t1.Store = 19
AND
Department = 80
GROUP BY
klDate
, Category
, reason
When I place this into the Dataset and Query Dialog of Jasper Studio, I get the same error and I am unable to use the SET sql_mode = ''; command. Any thoughts? If there is a way to achieve this without using SET sql_mode = '';?
I'm guessing the error is from this line in your select:
round(t1.loss / t2.loss,2) AS Percentage
Since you GROUP BY clause does not include this column it's somewhat of a coin toss which t1.loss and t2.loss values will be used. In some cases those values happen to always be the same based on your criteria and so you get the correct results regardless, but the db will still complain since it's being asked to return somewhat arbitrary results for those columns. One way to deal with this would be to simply apply an aggregate function to the columns in question like this:
round(min(t1.loss) / min(t2.loss),2) AS Percentage
or...
round(avg(t1.loss) / avg(t2.loss),2) AS Percentage
I think you want to do this :
round(sum(t1.loss / t2.loss)/count(*),2) AS Percentage
this will calculate the sum of the average loss for every records in the result then divide it on the the count of the record of the group it's like average of average.
EDITS:
sorry i made a syntax error now ,it should give the th wanted result and the error is because you are not using aggregate function on a column that is not in group by clause

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

Mysql query issue with if statements in select

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).