在所有SELECT字段中导致NULL的空表

时间:2013-08-19 03:15:36

标签: mysql

我有一个表chat,用于控制从所有其他表中读取的消息。对于新用户,我正在插入新值。

INSERT INTO chat VALUES (1,aaa,bbb,ccc)
SELECT
MAX(chatA.postOrder) AS aaa,
MAX(chatB.postOrder) AS bbb,
MAX(chatC.postOrder) AS ccc
FROM `chatA`, `chatB`, `chatC`
WHERE 1

对于ChatBChatC,postOrder存在且两者都有值。一切正常。问题是,有时聊天是空的(在这种情况下,chatA)。发生这种情况时,bbbccc将变为NULL。如果我删除此行MAX(chatA.postOrder) AS aaa,,则值仍为NULL。

我被困在这里,无法找到解决这个问题的方法。在选择字段中所做的更改(例如IFNULL(chatA.postOrder,0) AS aaa,)对结果没有影响。 chatA字段中的FROM似乎会导致bbbccc的结果为NULL。

修改:格式化

2 个答案:

答案 0 :(得分:1)

为什么不尝试结合所有

SELECT MAX(aaa) AS aaa, MAX(bbb) AS bbb, MAX(ccc) AS ccc from (
SELECT MAX(IFNULL(chatA.postOrder,0)) AS aaa, 0 as bbb, 0 AS ccc FROM `chatA`
UNION ALL
SELECT 0 AS aaa, MAX(IFNULL(chatB.postOrder,0)) AS bbb, 0 AS ccc FROM `chatB`
UNION ALL
SELECT 0 AS aaa, 0 AS bbb, MAX(IFNULL(chatC.postOrder,0)) AS ccc FROM `chatC`) 
AS derived_table;

这更合适,因为您没有尝试“加入”表格。我假设价值不会是负数,如果他们那么0就不会是一个好的数字,可能是一个永远不会出现在你的结果中的负数

答案 1 :(得分:0)

要确保在任何这些表为空时返回一行,您可以这样:

SELECT MAX(IF(t.chat='a',t.postOrder,NULL) AS aaa
     , MAX(IF(t.chat='b',t.postOrder,NULL) AS bbb
     , MAX(IF(t.chat='c',t.postOrder,NULL) AS ccc
  FROM ( SELECT 'a' AS `chat`, MAX(ta.postOrder) AS postOrder FROM `chatA` ta
          UNION ALL
         SELECT 'b', MAX(tb.postOrder) FROM `chatB` tb
          UNION ALL
         SELECT 'c', MAX(tc.postOrder) FROM `chatB` tc
       ) t

注意:内联视图(上面指定了t的别名)从三个表中的每个返回最大的postOrder。如果表为空(没有行),则该表中的SELECT将不返回行。但由于这些行将与UNION ALL运算符连接在一起。这给出了一个结果集,外部查询可以从中选择。在每一行上,我们添加一个常量文字鉴别器('a''b''c'),用于标识从中返回行的表。

外部查询中的“技巧”是测试鉴别器列,并仅在该列与postOrder中指定的列匹配时返回IF的值。否则,我们返回NULL。在MAX()聚合函数中包装IF()表达式有效地将三行折叠成一行。


您的查询是有效的:

SELECT MAX(a.postOrder) AS aaa
     , MAX(a.postOrder) AS bbb
     , MAX(a.postOrder) AS ccc
  FROM `chatA` a
 CROSS
  JOIN `chatB` b
 CROSS
  JOIN `chatC` c

由于JOIN操作,如果这三个表中的任何一个为空(不返回行),则查询根本不返回任何行。