为什么使用union all的查询不起作用

时间:2013-02-05 16:21:23

标签: mysql sql select

我有以下查询:

SELECT a.status, count(a.status) FROM
(SELECT 'Delivered' AS status
UNION ALL SELECT 'Buffered'
UNION ALL SELECT 'Not Delivered'
UNION ALL SELECT 'Not Reported') a
LEFT JOIN 
bulk_sms_numbers
ON a.status = bulk_sms_numbers.delivery_status
WHERE bulk_sms_id = 52
GROUP BY a.status;

以及以下结果:

+-----------+-----------------+
|  status   | count(a.status) |
+-----------+-----------------+
| Buffered  |              10 |
| Delivered |            3200 |
+-----------+-----------------+

我希望结果集包含union all查询中列出的所有可能状态

我需要的输出示例。

+---------------+-----------------+
|    status     | count(a.status) |
+---------------+-----------------+
| Buffered      |              10 |
| Delivered     |            3200 |
| Not Delieverd |               0 |
| Not Reported  |               0 |
+---------------+-----------------+

我正在使用MySql

4 个答案:

答案 0 :(得分:5)

将条件从WHERE子句移动到ON,因此过滤将在加入时进行,而不是在最终结果列表中进行。

SELECT a.status, count(a.status) 
FROM
    (
        SELECT 'Delivered' AS status
        UNION ALL SELECT 'Buffered'
        UNION ALL SELECT 'Not Delivered'
        UNION ALL SELECT 'Not Reported'
    ) a
    LEFT JOIN bulk_sms_numbers
        ON a.status = bulk_sms_numbers.delivery_status AND 
            bulk_sms_id = 52
GROUP BY a.status;

答案 1 :(得分:1)

尝试将WHERE条件移动到ON子句并使用OUTER连接。

SELECT a.status, count(a.status) FROM
(SELECT 'Delivered' AS status
UNION ALL SELECT 'Buffered'
UNION ALL SELECT 'Not Delivered'
UNION ALL SELECT 'Not Reported') a
LEFT OUTER JOIN 
bulk_sms_numbers
ON a.status = bulk_sms_numbers.delivery_status
AND bulk_sms_id = 52
GROUP BY a.status;

答案 2 :(得分:0)

尝试同时为所有人提供列名,并将ON更改为条件

SELECT a.status, count(a.status) FROM
(SELECT 'Delivered' AS status
UNION ALL SELECT 'Buffered' As status
UNION ALL SELECT 'Not Delivered' as status
UNION ALL SELECT 'Not Reported' as status) a
LEFT JOIN 
bulk_sms_numbers
ON a.status = bulk_sms_numbers.delivery_status
AND bulk_sms_id = 52
GROUP BY a.status;

答案 3 :(得分:0)

我最终使用了这样的查询:

SELECT cnt, IFNULL(delivery_status, 'Not Reported') delivery_status FROM (
    SELECT delivery_status, count(delivery_status) cnt FROM bulk_sms_numbers WHERE bulk_sms_id = 52 GROUP BY delivery_status
) x

然后在php中我将所有状态的默认值设置为0

$data = $db->fetchAll($q, array($aid, $reference));

$statuses = array(
    'Buffered' => 0,
    'Delivered' => 0,
    'Not Delivered' => 0,
    'Not Reported' => 0,
);

foreach ($data as $value) {
    $statuses[$value['delivery_status']] = $value['cnt'];
}

虽然这解决了我的问题,但不是我的问题的答案。 我想找一个纯粹的SQL答案。