2012-12-16 26 views
4

我有兩個表,我用UNION ALL查詢 - 一個用於Android,一個用於iPhone。每個表都有自己的設備字段(「android」或「iphone」)。MySQL中的GROUP_CONCAT - 如何包含不同的值?

我使用GROUP_CONCAT(DISTINCT `device` ORDER BY `device` SEPARATOR ', ') AS `device`幾次,每次當我被另一個列組(如日期,USER_ID等)。我也使用相同的GROUP_CONCAT來計算總數。

的問題是,當I組由日期,我選擇設備(未直接在設備)的GROUP_CONCAT因爲有一些日期那裏有Android和iPhone購買。選擇還包括WHERE或HAVING讓用戶按特定日期過濾,加入日期等的用戶數。當我計算總計時,我在設備上有GROUP_CONCAT,它本身是一個GROUP_CONCAT函數。結果可能類似於「android,android,iphone,iphone」,因爲只有Android的日期,僅有iPhone的日期和兩者的日期(其他查詢只能有一個或一些這些選項)。我正在尋找一種方法將此結果轉換爲「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(返回的結果也應該有一個大寫的A中的「Android」和資本P在「iPhone」中,但我不介意使用PHP函數)。

順便說一下,總的SELECT查詢是SELECT .... FROM(SELECT .... FROM(.... UNION ALL ....)GROUP BY ....)和GROUP BY在裏面。如果我沒有在內部查詢中包含設備,那麼在外部查詢中將不會有設備到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` 

感謝, URI。

+0

沒有人可以幫助你,如果你不發佈實際查詢。 –

回答

0

只是一個草案來說明一個想法:使用「虛擬」表

select d1.device, d2.device, ... 
from (
    select 'android' as device 
    union 
    select 'iphone' as device 
    ) as devices 
left outer join mydata d1 on d1.device = devices.device and devices.device = 'android' 
left outer join mydata d2 on d2.device = devices.device and devices.device = 'iphone' 
inner join ... 
where ... 

和外部連接,你可以得到所有記錄androidiphone這樣或者兩個設備都是非空或至少其中一個是非空的。 如果您喜歡或者以任何其他合適的方式對它們進行評估,您可以將d1.deviced2.device連接到group by這些。