MySQL ГРУППИРУЕТ ПО столбцу, игнорируя конкретное значение

#mysql

#mysql

Вопрос:

У меня есть запрос к таблице телефонных звонков, который использует GROUP BY для отображения только уникальных идентификаторов вызывающих абонентов. Проблема в том, что если у вызывающего абонента заблокирован идентификатор вызывающего абонента, его идентификатор вызывающего абонента отображается как «Неизвестный», и клиент не хочет, чтобы все неизвестные суммировались вместе. Итак, в принципе, вместо того, чтобы просто GROUP BY caller_id мне нужно как-то сделать что-то вроде GROUP BY caller_id IF caller_id != 'Unknown'

Возможно ли это вообще? Я бы хотел избежать выполнения всей групповой обработки в PHP, если это вообще возможно.

Комментарии:

1. Разве для этого не используется оператор WHERE?

2. Ответ VladoDemcak кажется нормальным … это работает для вас?

Ответ №1:

Вы можете сделать что-то вроде:

SELECT caller_id FROM phone_calls WHERE caller_id != 'Unknown' GROUP BY caller_id;

или рассмотрите DISTINCT — в большинстве случаев это быстрее — если у вас есть индекс, созданный для caller_id, производительность обычно такая же, но если не DISTINCT, то лучше. Если вам нужно :

… показывать только уникальные идентификаторы вызывающих абонентов..

но, возможно, для вашего случая (выполнение агрегации или что-то подобное) вы не можете его использовать, но на всякий случай:

SELECT DISTINCT caller_id FROM phone_calls WHERE caller_id != 'Unknown' ;

— РЕДАКТИРОВАТЬ ПОСЛЕ обсуждения в комментариях

 SELECT * FROM callers;                                                                                                                                                                                             
 ---- ----------- -----------                                                                                                                                                                                                         
| id | caller_id | call_time |                                                                                                                                                                                                        
 ---- ----------- -----------                                                                                                                                                                                                         
|  1 | abc       |        24 |                                                                                                                                                                                                        
|  2 | abc       |        16 |                                                                                                                                                                                                        
|  3 | xyz       |        10 |                                                                                                                                                                                                        
|  4 | xyz       |        10 |                                                                                                                                                                                                        
|  5 | Unknown   |        11 |                                                                                                                                                                                                        
|  6 | Unknown   |        12 |                                                                                                                                                                                                        
|  7 | Unknown   |        13 |                                                                                                                                                                                                        
|  8 | xyz       |         1 |                                                                                                                                                                                                        
|  9 | abc       |        10 |                                                                                                                                                                                                        
 ---- ----------- -----------    

SELECT caller_id, SUM(call_time) FROM callers 
WHERE caller_id != 'Unknown' 
GROUP BY caller_id;                                                                                                                     
 ----------- ----------------                                                                                                                                                                                                         
| caller_id | SUM(call_time) |                                                                                                                                                                                                        
 ----------- ----------------                                                                                                                                                                                                         
| abc       |             50 |                                                                                                                                                                                                        
| xyz       |             21 |                                                                                                                                                                                                        
 ----------- ----------------                                                                                                                                                                                                         

SELECT caller_id, SUM(call_time) FROM callers
GROUP BY caller_id;                                                                                                                                                  
 ----------- ----------------                                                                                                                                                                                                         
| caller_id | SUM(call_time) |                                                                                                                                                                                                        
 ----------- ----------------                                                                                                                                                                                                         
| abc       |             50 |                                                                                                                                                                                                        
| Unknown   |             36 |                                                                                                                                                                                                        
| xyz       |             21 |                                                                                                                                                                                                        
 ----------- ----------------                                                                                                                                                                                                         

SELECT caller_id, SUM(call_time) as total_time FROM callers 
WHERE caller_id != 'Unknown' 
GROUP BY caller_id 
UNION 
SELECT caller_id, call_time FROM callers 
WHERE caller_id = 'Unknown';                             
 ----------- ------------                                                                                                                                                                                                              
| caller_id | total_time |                                                                                                                                                                                                             
 ----------- ------------                                                                                                                                                                                                              
| abc       |         50 |                                                                                                                                                                                                             
| xyz       |         21 |                                                                                                                                                                                                             
| Unknown   |         11 |                                                                                                                                                                                                             
| Unknown   |         12 |                                                                                                                                                                                                             
| Unknown   |         13 |                                                                                                                                                                                                             
 ----------- ------------                                                                                                                                                                                                              

SELECT caller_id, SUM(call_time) as total_time FROM callers
GROUP BY caller_id, 
      (case when caller_id = 'Unknown' 
       AND id is not null 
       then id end
       );                                                                   
 ----------- ------------                                                                                                                                                                                                              
| caller_id | total_time |                                                                                                                                                                                                             
 ----------- ------------                                                                                                                                                                                                              
| abc       |         50 |                                                                                                                                                                                                             
| Unknown   |         11 |                                                                                                                                                                                                             
| Unknown   |         12 |                                                                                                                                                                                                             
| Unknown   |         13 |                                                                                                                                                                                                             
| xyz       |         21 |                                                                                                                                                                                                             
 ----------- ------------  
 

Комментарии:

1. Мы выполняем агрегацию, поэтому DISTINCT не работает. И мы по-прежнему хотим, чтобы неизвестные вызовы отображались, просто каждый как своя группа (поэтому каждый вызов с идентификатором вызывающего абонента Unknown будет отображаться в результатах со счетом 1), и я думаю, что предложение WHERE полностью удалит их. Это сработало бы, если бы я просто сделал второй запрос, чтобы выбирать только вызовы с caller_id из Unknown и не выполнять никакой группировки по этому второму запросу

2. Хорошо, теперь я понимаю, что вам действительно нужно. Есть одна возможность, но сейчас я не могу ее проверить, но вы можете попробовать «группировать по caller_id, (случай, когда caller_id = ‘Unknown’ и unique_col не равен нулю, тогда unique_col заканчивается);» но для неизвестной группы должен быть уникальный столбец. В противном случае, я думаю, вам понадобятся два выбора и объединение их.

3. @awestover89 проверьте мой ответ, я добавил примеры, это было бы вам интересно

4. В итоге я создал переменную. Рассматриваемый запрос уже составлял около 60 строк, поэтому ОБЪЕДИНЕНИЕ было бы ужасно неэффективным. Мое окончательное решение оказалось чем-то вроде: IF (0 = ani REGEXP ‘^[ ]?[0-9] $’,@ani_count:=@ani_count 1,@ani_count:=0) КАК unknown_count, а затем добавил unknown_count в группу. Я думаю, что функционально это ведет себя так же, как и ваш последний пример.

5. По сути, я создал переменную, которая была бы одинаковой для всех числовых идентификаторов вызывающих абонентов и уникальным значением для любого нечислового caller_id, поэтому, когда я группируюсь по ani и unknown_count, нечисловые идентификаторы вызывающих абонентов находятся в отдельной группе.