Select 查询 returns 如果子查询在 from 子句中失败则为 NULL

Select Query returns NULL if subquery fails in the from Clause

我有两个 table trans_transaction 和 opening_balances。 交易将被插入 trans_transaction table。 我需要从 trans_transaction table 中获取 opening_balance、closing_balance。 opening_balancestable是在trans_transactiontable的账户没有交易时第一次使用。 我也写了一个查询,但是如果 trans_transaction table 中没有记录并且无法从 opening_balances table[=14= 中获取数据,则查询失败]

SELECT `aasr`.`account_id`, `aasr`.`sub_account_id`, `aasr`.`opening_balance` `oob`, `aasr`.`shadow_opening_balance` `osb`, `aasr`.`lein_opening_balance` `olb`, `tt`.`opening_balance` `ob`, `tt`.`closing_balance` `cb`, `tt`.`shadow_balance` `sb`, `tt`.`lein_balance` `lb`
FROM `accnt_acc_subacc_rel` `aasr`,
    (
        SELECT `tti`.`transaction_id`, `tti`.`accounts_id`, `tti`.`sub_account_id`, `tti`.`opening_balance`, `tti`.`closing_balance`, `tti`.`shadow_balance`, `tti`.`lein_balance`
        FROM `trans_transaction` `tti`
        WHERE `tti`.`accounts_id` = 10 AND `tti`.`sub_account_id` = 20 AND `tti`.`effective_date` <= '2014-10-12 23:59:59'
        ORDER BY `tti`.`effective_date` DESC, `tti`.`transaction_id` DESC
    ) `tt`
WHERE `aasr`.`account_id` = 10 AND `aasr`.`sub_account_id` = 20
LIMIT 1

我也试过使用下面的查询,但是如果 SubQuery returns 0 行

它仍然失败
SELECT  `aasr`.`account_id`, `aasr`.`sub_account_id`,
            IF(`tt`.`opening_balance` = '', `aasr`.`opening_balance`, `tt`.`opening_balance`) AS `opening_balance`,
            IF(`tt`.`closing_balance` = '', `aasr`.`opening_balance`, `tt`.`closing_balance`) AS `closing_balance`,
            IF(`tt`.`shadow_balance` = '', `aasr`.`shadow_opening_balance`, `tt`.`opening_balance`) AS `shadow_balance`,
            IF(`tt`.`lein_balance` = '', `aasr`.`lein_opening_balance`, `tt`.`lein_balance`) AS `lein_balance`
    FROM `accnt_acc_subacc_rel` `aasr`,
        (
            SELECT `tti`.`transaction_id`, `tti`.`accounts_id`, `tti`.`sub_account_id`, `tti`.`opening_balance`, `tti`.`closing_balance`, `tti`.`shadow_balance`, `tti`.`lein_balance`
            FROM `trans_transaction` `tti`
            WHERE `tti`.`accounts_id` = 10 AND `tti`.`sub_account_id` = 20 AND `tti`.`effective_date` <= '2014-10-12 23:59:59'
            ORDER BY `tti`.`effective_date` DESC, `tti`.`transaction_id` DESC
            LIMIT 1
        ) `tt`
    WHERE `aasr`.`account_id` = 10 AND `aasr`.`sub_account_id` = 20

我不明白哪里出了问题...

按照@BaconBits 的建议使用 "LEFT OUTER JOIN" 和 IFNULL:

SELECT  `aasr`.`account_id`, `aasr`.`sub_account_id`,
        IFNULL(`tt`.`opening_balance`, `aasr`.`opening_balance`) AS `opening_balance`,
        IFNULL(`tt`.`closing_balance`, `aasr`.`opening_balance`) AS `closing_balance`,
        IFNULL(`tt`.`shadow_balance`, `aasr`.`shadow_opening_balance`) AS `shadow_balance`,
        IFNULL(`tt`.`lein_balance`, `aasr`.`lein_opening_balance`) AS `lein_balance`
FROM `accnt_acc_subacc_rel` `aasr`
LEFT OUTER JOIN
    (
        SELECT `tti`.`transaction_id`, `tti`.`accounts_id`, `tti`.`sub_account_id`, `tti`.`opening_balance`, `tti`.`closing_balance`, `tti`.`shadow_balance`, `tti`.`lein_balance`
        FROM `trans_transaction` `tti`
        WHERE `tti`.`accounts_id` = 10 AND `tti`.`sub_account_id` = 20 AND `tti`.`effective_date` <= '2014-10-12 23:59:59'
        ORDER BY `tti`.`effective_date` DESC, `tti`.`transaction_id` DESC
        LIMIT 1
    ) `tt` 
    ON `aasr`.`accounts_id` = `tt`.`accounts_id` AND `aasr`.`sub_account_id` = `tt`.`sub_account_id` 
WHERE `aasr`.`account_id` = 10 AND `aasr`.`sub_account_id` = 20

(@Nikhilesh_Manurkar 在评论中询问是否可以不使用子查询,所以:)

在没有子查询的情况下进行(小心!!!使用这些 WHERE 条件,在子查询中首先过滤 trans_transaction 更有效):

SELECT  
    `aasr`.`account_id`,
    `aasr`.`sub_account_id`,
    IFNULL(`tt`.`opening_balance`, `aasr`.`opening_balance`) AS `opening_balance`,
    IFNULL(`tt`.`closing_balance`, `aasr`.`opening_balance`) AS `closing_balance`,
    IFNULL(`tt`.`shadow_balance`, `aasr`.`shadow_opening_balance`) AS `shadow_balance`,
    IFNULL(`tt`.`lein_balance`, `aasr`.`lein_opening_balance`) AS `lein_balance`

FROM 
    `accnt_acc_subacc_rel` `aasr`

LEFT OUTER JOIN 
    `trans_transaction` `tt`
    ON 
        `aasr`.`accounts_id` = `tt`.`accounts_id` 
        AND `aasr`.`sub_account_id` = `tt`.`sub_account_id` 

WHERE 
    `aasr`.`account_id` = 10 
    AND `aasr`.`sub_account_id` = 20 
    # case no record in `tt` to match `aasr` join, `tt`.`effective_date` would be null,
    # so you should add this to the "WHERE" condition
    AND ( `tt`.`effective_date` <= '2014-10-12 23:59:59' OR ISNULL `tt`.`effective_date`)

ORDER BY 
    `tt`.`effective_date` DESC, `tt`.`transaction_id` DESC