我有这张桌子:
+--------------+-----------------------------+----------------+
| Username | Message | Status |
+--------------+-----------------------------+----------------+
| jamesbond | I need some help | SendingOK |
| jamesbond | I need some help | SendingOK |
| jamesbond | I need some help | SendingFailed |
| jamesbond | Mission accomplished | SendingOK |
+--------------+-----------------------------+----------------+
由此SQL语法生成:
SELECT A.Username, A.Message, B.Status
FROM db1.SmsBroadcast as A
INNER JOIN db2.sentitems as B
ON A.MessageSMS1 = B.TextDecoded
WHERE A.Username = 'jamesbond'
GROUP BY Message, Status
现在如何获得此输出?
+--------------+-----------------------------+-----------+---------------+
| Username | Message | SendingOK | SendingFailed |
+--------------+-----------------------------+-----------+---------------+
| jamesbond | I need some help | 2 | 1 |
| jamesbond | Mission accomplished | 1 | 0 |
+--------------+-----------------------------+-----------+---------------+
SendingOK
和SendingFailed
列实际上可以使用COUNT(*)
计算,但我不知道如何基于相同的Message进行计数,而这些消息是以相同的SQL语法执行的。任何想法怎么做?
答案 0 :(得分:3)
试试这个:
SELECT A.Username, A.Message,
SUM(CASE WHEN B.Status = 'SendingOK' THEN 1 ELSE 0 END) AS SendingOK ,
SUM(CASE WHEN B.Status = 'SendingFailed' THEN 1 ELSE 0 END) AS SendingFailed,
FROM db1.SmsBroadcast as A
INNER JOIN db2.sentitems as B ON A.MessageSMS1 = B.TextDecoded
WHERE A.Username = 'jamesbond'
GROUP BY A.Username, A.Message
答案 1 :(得分:2)
如果您有一定数量的值可以转换为列,那么您可以像其他答案一样对它们进行硬编码。但如果您的号码未知,则可以使用prepared statements:
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'SUM(case when Status = ''',
Status,
''' then 1 else 0 end) AS ',
Status
)
) INTO @sql
FROM db2.sentitems;
SET @sql = CONCAT('SELECT A.Username, A.Message, ', @sql, '
FROM db1.SmsBroadcast A
INNER JOIN db2.sentitems B
ON A.MessageSMS1 = B.TextDecoded
WHERE A.Username = ''jamesbond''
GROUP BY A.Username, A.Message');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
与此相关的主要区别在于它根据db2.sentitems
中的值生成SQL字符串,因此如果值发生更改,则会自动调整,而无需更改代码。
答案 2 :(得分:1)
您只需在CASE
声明中使用SELECT
,然后username
和message
对其进行分组。
SELECT `UserName`,
`Message`,
SUM(CASE WHEN `status` = 'SendingOK' THEN 1 ELSE 0 END) OkStat,
SUM(CASE WHEN `status` = 'SendingFailed' THEN 1 ELSE 0 END) FailedStat
FROM db1.SmsBroadcast as A
JOIN db2.sentitems as B
ON A.MessageSMS1 = B.TextDecoded
WHERE A.Username = 'jamesbond'
GROUP BY A.Username, A.Message