我有一个表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
对于ChatB
和ChatC
,postOrder存在且两者都有值。一切正常。问题是,有时聊天是空的(在这种情况下,chatA
)。发生这种情况时,bbb
和ccc
将变为NULL。如果我删除此行MAX(chatA.postOrder) AS aaa,
,则值仍为NULL。
我被困在这里,无法找到解决这个问题的方法。在选择字段中所做的更改(例如IFNULL(chatA.postOrder,0) AS aaa,
)对结果没有影响。 chatA
字段中的FROM
似乎会导致bbb
和ccc
的结果为NULL。
修改:格式化
答案 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操作,如果这三个表中的任何一个为空(不返回行),则查询根本不返回任何行。