1

我有这张桌子:

+--------------+-----------------------------+----------------+
| 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             |
+--------------+-----------------------------+-----------+---------------+

SendingOKSendingFailed列实际上可以使用计算COUNT(*),但我不知道如何基于相同的消息进行计数,而这些消息以相同的 SQL 语法执行。知道怎么做吗?

4

3 回答 3

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 
于 2012-10-02T11:59:16.480 回答
2

如果您有已知数量的值要变成列,那么您可以像其他答案一样对它们进行硬编码。但是如果你有一个未知的数字,那么你可以使用准备好的语句

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;

与此的主要区别在于它根据您的值生成 SQL 字符串,db2.sentitems因此如果值发生更改,那么它将自动调整而无需更改您的代码。

于 2012-10-02T12:04:01.517 回答
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
于 2012-10-02T11:59:28.573 回答