UNIONALLでクエリを実行するテーブルが2つあります。1つはAndroid用、もう1つはiPhone用です。各テーブルには、独自のデバイスフィールド(「android」または「iphone」)があります。
GROUP_CONCAT(DISTINCT `device` ORDER BY `device` SEPARATOR ', ') AS `device`
別の列(date、user_idなど)でグループ化するたびに、数回使用します。また、同じGROUP_CONCATを使用して合計を計算します。
問題は、日付でグループ化するときに、AndroidとiPhoneの両方の購入がある日付があるため、デバイスのGROUP_CONCATを選択することです(デバイスを直接ではありません)。選択には、ユーザーが特定の日付、日付に参加したユーザーの数などでフィルタリングできるようにするWHEREまたはHAVINGも含まれます。合計を計算すると、デバイスにGROUP_CONCATがあり、それ自体がGROUP_CONCAT関数です。Androidのみの日付、iPhoneのみの日付、および両方の日付があるため、結果は「android、android、iphone、iphone」のようになります(他のクエリには、これらのオプションの1つまたは一部のみを含めることができます)。この結果を「android、iphone」に変換する方法を探しています。
現在、PHP関数を使用しています。
private function get_device_human_string($fp_device_computer_string)
{
$devices= array(
'android' => 'Android',
'iphone' => 'iPhone'
);
$device_computer_string= strtolower($fp_device_computer_string);
$ret= array();
foreach ($devices as $device_key => $device_human_string)
{
if (strpos($device_computer_string, $device_key) !== false)
{
$ret[]= $device_human_string;
}
}
return implode(', ', $ret);
}
しかし、MySQLでそれを行う方法を探しています(返される結果には、「Android」では大文字のA、「iPhone」では大文字のPが必要ですが、PHP関数を使用してもかまいません) 。
ちなみに、合計SELECTクエリはSELECT .... FROM(SELECT .... FROM(.... UNION ALL ....)GROUP BY ....)であり、GROUPBYは内部にあります。内部クエリにデバイスを含めない場合、外部クエリにGROUP_CONCATするデバイスはありません。そのため、デバイスで直接GROUP_CONCATを実行することはできません。
編集:これは私が使用しているクエリの例です(WHEREとHAVINGはユーザーのフィルターに応じて変更できます):
SELECT
COUNT(1) AS `count`,
SUM(`joined`) AS `joined`,
SUM(`users`) AS `users`,
SUM(`purchases`) AS `purchases`,
SUM(`credits_purchased`) AS `credits_purchased`,
GROUP_CONCAT(DISTINCT `device` ORDER BY `device` SEPARATOR ', ') AS `device`,
GROUP_CONCAT(DISTINCT `application` ORDER BY `application` SEPARATOR ', ') AS `application`
FROM (
SELECT
`all_purchases`.*,
IF(`users_joined`.`joined` IS NOT NULL, `users_joined`.`joined`, 0) AS `joined`,
'esalne' AS `application`
FROM (
SELECT
DATE(`date`) AS `date`,
COUNT(DISTINCT `user_id`) AS `users`,
COUNT(1) AS `purchases`,
SUM(
IF(
STRCMP(SUBSTRING(`item`, 1, CHAR_LENGTH('esalne.sip.')), 'esalne.sip.')=0,
CAST(SUBSTRING(`item`, CHAR_LENGTH('esalne.sip.')+1) AS UNSIGNED INTEGER),
0
)
) AS `credits_purchased`,
GROUP_CONCAT(DISTINCT `device` ORDER BY `device` SEPARATOR ', ') AS `device`
FROM (
(
SELECT
`id`,
`item`,
`date`,
`status`,
`user` AS `user_id`,
NULL AS `transaction_id`,
'android' AS `device`
FROM `enswitch_android_purchases`
WHERE (`status`=1)
AND (`user` IS NOT NULL)
)
UNION ALL
(
SELECT
`id`,
`item`,
`date`,
`status`,
`user` AS `user_id`,
`transaction_id`,
'iphone' AS `device`
FROM `enswitch_iphone_purchases`
WHERE (`status`=1)
AND (`user` IS NOT NULL)
)
) AS `all_purchases`
GROUP BY DATE(`date`)
) AS `all_purchases`
LEFT JOIN (
SELECT
`join_date` AS `date`,
COUNT(1) AS `joined`
FROM (
SELECT
`user_id`,
MIN(DATE(`date`)) AS `join_date`
FROM (
(
SELECT
`id`,
`item`,
`date`,
`status`,
`user` AS `user_id`,
NULL AS `transaction_id`,
'android' AS `device`
FROM `enswitch_android_purchases`
WHERE (`status`=1)
AND (`user` IS NOT NULL)
)
UNION ALL
(
SELECT
`id`,
`item`,
`date`,
`status`,
`user` AS `user_id`,
`transaction_id`,
'iphone' AS `device`
FROM `enswitch_iphone_purchases`
WHERE (`status`=1)
AND (`user` IS NOT NULL)
)
) AS `all_purchases`
GROUP BY `user_id`
) AS `users`
GROUP BY `date`
) AS `users_joined` ON (`all_purchases`.`date`=`users_joined`.`date`)
HAVING (`date` >= DATE_ADD('2012-11-01', INTERVAL 0 DAY))
AND (`date` < DATE_ADD('2012-11-30', INTERVAL 1 DAY))
AND (`joined` >= 2)
AND (`purchases` <= 30)
AND (`credits_purchased` <= 3000)
) AS `all_purchases_by_dates`
ありがとう、ウリ。