【问题标题】:sql select - another select with NULL returns only NULLsql select - 另一个带有 NULL 的选择仅返回 NULL
【发布时间】:2012-03-24 02:45:45
【问题描述】:

我有一个像下面这样的一个,它从另一个选择中减去。我遇到的问题是,如果第二个 SELECT(要减去的那个)返回 NULL,即使第一个查询有值,完整查询也会返回 NULL。似乎 MySQL 认为1-NULL=NULL。我该如何解决这个问题?

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)

【问题讨论】:

  • 不只是 MySQL - 这甚至不只是 SQL - 这就是 NULL 的行为方式 - 句号。
  • @Dems:看看1-0=0 是如何被认为是普遍真理,但我认为1-NULL=NULL 不能这么说。相反,它是由 SQL 标准定义**并由 mySQL 实现的。 ** 我的意思是松散!
  • @onedaywhen - 除了 NULL 不是纯粹的 SQL 概念。它已经超越了。
  • @Dems:你有引用吗?

标签: mysql sql


【解决方案1】:

也许你可以用 IFNULL 包装“内部”sql

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)

【讨论】:

    【解决方案2】:

    对 null 执行任何操作都会返回 null。如果它为空,您需要使用 COALESCE 或 IFNULL 定义您想要发生的事情。 以http://www.w3schools.com/sql/sql_isnull.asp 为例。

    【讨论】:

    • “用 null 做任何事情都会返回 null”——NULL IS NULL 的计算结果为 TRUE。
    【解决方案3】:

    似乎 MySQL 认为 1-NULL=NULL

    是的;这是正确的。 “一”减去“未知”就是“未知”。如果您希望将第二个子查询的NULL 视为0,则需要将其包装在对the COALESCE operator 的调用中:将(SELECT ...) 更改为COALESCE((SELECT ...), 0)

    【讨论】:

      猜你喜欢
      • 2018-09-03
      • 1970-01-01
      • 2023-03-27
      • 2021-07-05
      • 1970-01-01
      • 1970-01-01
      • 2021-12-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多