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

SendingOK列は実際にはをSendingFailed使用して計算できますが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し、とでグループ化するだけです。SELECTusernamemessage

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 に答える