0

I have a like the one below that does a minus from another select. The problem I have is that if the second SELECT (the one to do minus with) returns NULL, the full query returns NULL even if the first query has values. Seems like MySQL thinks 1-NULL=NULL. How can I fix this?

SELECT round(sum(iv.`amount`)) - 
(
 SELECT round(sum(pay.`amount`)) amountSum

     FROM invoice iv
    LEFT JOIN invoiceFactoring ivf on ivf.invoiceID=iv.invoiceID 
    LEFT JOIN user systemuser ON (systemuser.userID=iv.ownerUserID)
    LEFT JOIN Payment pay ON (pay.`invoiceID`=iv.`invoiceID`)
     WHERE 
        (iv.invoiceStateID = 2 OR iv.invoiceStateID = 3) 
     AND 
    (ivf.`invoiceFactoringProcessID` = 7)
     AND     (pay.`paymentMethodID` = 1 OR pay.`paymentMethodID` = 2)
     AND systemuser.`groupID` = 1 
     AND iv.`disabled` <> 1 
     AND ivf.`invoiceExpiryDate` BETWEEN date_add(now(), INTERVAL - 28 DAY) AND date_add(now(), INTERVAL - 21 DAY)

)
    FROM invoice iv
    LEFT JOIN invoiceFactoring ivf on ivf.invoiceID=iv.invoiceID 
        LEFT JOIN user systemuser ON (systemuser.userID=iv.ownerUserID)
    WHERE 
    (iv.invoiceStateID = 2 OR iv.invoiceStateID = 3)
        AND 
    (ivf.`invoiceFactoringProcessID` = 7 or ivf.`invoiceFactoringProcessID`)
    AND systemuser.`groupID` = 1 
    AND iv.`disabled` <> 1   /* ta bort de som är inaktiva*/    
    AND ivf.`invoiceExpiryDate` BETWEEN date_add(now(), INTERVAL - 28 DAY) AND date_add(now(), INTERVAL - 21 DAY)
4
  • That's not just MySQL - That's not even just SQL - That's how NULL is defined to behave - period. Commented Feb 3, 2012 at 13:45
  • @Dems: see how 1-0=0 can be considered a universal truth but I don't think the same can be said of 1-NULL=NULL. Rather, it is something defined** by the SQL Standard and implemented by mySQL. ** I mean that loosely! Commented Feb 3, 2012 at 14:52
  • @onedaywhen - Except that NULL isn't a purely SQL concept. It's since transcended that. Commented Feb 3, 2012 at 15:19
  • @Dems: do you have a citation for that? Commented Feb 6, 2012 at 8:15

3 Answers 3

1

perhaps you can wrap the "inner" sql with an IFNULL

SELECT round(sum(iv.`amount`)) - 
IFNULL((
 SELECT round(sum(pay.`amount`)) amountSum
 FROM invoice iv
 LEFT JOIN invoiceFactoring ivf on ivf.invoiceID=iv.invoiceID 
 LEFT JOIN user systemuser ON (systemuser.userID=iv.ownerUserID)
 LEFT JOIN Payment pay ON (pay.`invoiceID`=iv.`invoiceID`)
 WHERE 
    (iv.invoiceStateID = 2 OR iv.invoiceStateID = 3) 
 AND 
    (ivf.`invoiceFactoringProcessID` = 7)
 AND     (pay.`paymentMethodID` = 1 OR pay.`paymentMethodID` = 2)
 AND systemuser.`groupID` = 1 
 AND iv.`disabled` <> 1 
 AND ivf.`invoiceExpiryDate` BETWEEN date_add(now(), INTERVAL - 28 DAY) 
 AND date_add(now(), INTERVAL - 21 DAY)
),0)

FROM invoice iv
LEFT JOIN invoiceFactoring ivf on ivf.invoiceID=iv.invoiceID 
    LEFT JOIN user systemuser ON (systemuser.userID=iv.ownerUserID)
WHERE 
(iv.invoiceStateID = 2 OR iv.invoiceStateID = 3)
    AND 
(ivf.`invoiceFactoringProcessID` = 7 or ivf.`invoiceFactoringProcessID`)
AND systemuser.`groupID` = 1 
AND iv.`disabled` <> 1   /* ta bort de som är inaktiva*/    
AND ivf.`invoiceExpiryDate` BETWEEN date_add(now(), INTERVAL - 28 DAY) AND date_add(now(), INTERVAL - 21 DAY)
Sign up to request clarification or add additional context in comments.

Comments

0

Doing anything with a null returns null. You need to define what you want to happen if it is null using COALESCE or IFNULL. Check http://www.w3schools.com/sql/sql_isnull.asp for an example.

1 Comment

"Doing anything with a null returns null" -- NULL IS NULL evaluates to TRUE.
0

Seems like MySQL thinks 1-NULL=NULL.

Yes; and it is correct. "One" minus "unknown" is "unknown". If you want the second subquery's NULL to be treated as 0, then you need to wrap it in a call to the COALESCE operator: change (SELECT ...) to COALESCE((SELECT ...), 0).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.